-
Notifications
You must be signed in to change notification settings - Fork 2.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Introduce distinct ObjectMappers for RestEasy Reactive / RestEasy Reactive Client #23995
Conversation
Thanks a lot for this! To be honest, I would like to limit the scope of the change. What I had in mind was to have these separate Would you be interested in making these changes or do you want to open a new PR? |
Yes, we need to be extremely careful about that. |
What do you guys think about using |
Another thing we need to be careful about is backwards compatibility. You might have people relying on the existing behavior so we need to be careful. |
I've create #24019 to track using |
Limited the scope of the change per @geoand 's comments |
Thanks, I'll take a closer look soon. |
...steasy/reactive/jackson/runtime/serialisers/FullyFeaturedServerJacksonMessageBodyWriter.java
Outdated
Show resolved
Hide resolved
extensions/jackson/runtime/src/main/java/io/quarkus/jackson/runtime/ClientObjectMapper.java
Outdated
Show resolved
Hide resolved
This workflow status is outdated as a new workflow run has been triggered. Failing Jobs - Building 65a4a35
Full information is available in the Build summary check run. Failures⚙️ JVM Tests - JDK 11 #- Failing: extensions/smallrye-reactive-messaging-kafka/deployment
! Skipped: integration-tests/kafka-oauth-keycloak integration-tests/kafka-sasl-elytron integration-tests/kubernetes/quarkus-standard-way-kafka and 2 more 📦 extensions/smallrye-reactive-messaging-kafka/deployment✖
|
@geoand, Rebased and addressed concerns. I had to move annotations to Are the qualifier annotations in the package that you expect? |
...me/src/main/java/io/quarkus/resteasy/reactive/jackson/common/runtime/ClientObjectMapper.java
Outdated
Show resolved
Hide resolved
...me/src/main/java/io/quarkus/resteasy/reactive/jackson/common/runtime/ServerObjectMapper.java
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added a final round of comments.
We'll also need the commits squashed.
Thanks!
...me/src/main/java/io/quarkus/resteasy/reactive/jackson/common/runtime/ClientObjectMapper.java
Outdated
Show resolved
Hide resolved
...me/src/main/java/io/quarkus/resteasy/reactive/jackson/common/runtime/ServerObjectMapper.java
Outdated
Show resolved
Hide resolved
This workflow status is outdated as a new workflow run has been triggered. Failing Jobs - Building 54ef22d
Failures⚙️ Initial JDK 11 Build #- Failing: extensions/resteasy-reactive/quarkus-resteasy-reactive-jackson-common/runtime
! Skipped: devtools/bom-descriptor-json docs extensions/oidc-client-reactive-filter/deployment and 31 more 📦 extensions/resteasy-reactive/quarkus-resteasy-reactive-jackson-common/runtime✖ |
LGTM, thanks a lot! @gsmet any more comments on your side? |
Let's wait for Guillaume's comments |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added some minor suggestions but I have also one major concern we need to sort out. See inline.
...untime/src/main/java/io/quarkus/resteasy/reactive/jackson/common/RestClientObjectMapper.java
Outdated
Show resolved
Hide resolved
...untime/src/main/java/io/quarkus/resteasy/reactive/jackson/common/RestClientObjectMapper.java
Outdated
Show resolved
Hide resolved
...untime/src/main/java/io/quarkus/resteasy/reactive/jackson/common/RestClientObjectMapper.java
Outdated
Show resolved
Hide resolved
[source,java] | ||
---- | ||
import com.fasterxml.jackson.databind.ObjectMapper; | ||
import io.quarkus.resteasy.reactive.jackson.common.RestClientObjectMapper; | ||
import io.quarkus.resteasy.reactive.jackson.common.RestServerObjectMapper; | ||
|
||
import javax.inject.Inject; | ||
|
||
public class UseFallback { | ||
|
||
private final ObjectMapper serializer; | ||
|
||
@Inject | ||
public UseFallback(ObjectMapper mapper, | ||
@RestClientObjectMapper Instance<ObjectMapper> clientInstance) { | ||
serializer = clientInstance.isUnsatisfied() ? mapper : clientInstance.get(); | ||
} | ||
|
||
} | ||
---- |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure we really want to document this. These mappers are supposed to be used for a very specific purposes by the RESTEasy Reactive extension so I'm not sure I would document anything except the customization of them.
In any case, if we want to keep that (I recommend we don't), I would put it at the end, not at the start.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Makes sense to remove the fallback in this example. When would someone wish to inject the alternate ObjectMappers into non-quarkus code? Possibly/Probably an edge case.
...untime/src/main/java/io/quarkus/resteasy/reactive/jackson/common/RestServerObjectMapper.java
Outdated
Show resolved
Hide resolved
If you want to customize the unqualified, client, and server instances differently, you can use the `@RestClientObjectMapper` and | ||
`@RestServerObjectMapper` annotations on your `ObjectMapperCustomizer`. `ObjectMapperCustomizer` instances without any | ||
qualifier will customize all three `ObjectMapper`s. `ObjectMapperCustomizer` annotated with `@RestClientObjectMapper` will customize | ||
only the client instance. `ObjectMapperCustomizer` annotated with `@RestServerObjectMapper` will customize only the server instance. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmmmm. With the way it's documented, I would have expected the client and server instances to be created automatically if there are customizers and AFAICS from the code, it's not the case?
I.e. I would have expected the third part of the doc where you have to produce the ObjectMapper
yourselves to not be necessary as it's quite brittle and you could definitely get it wrong doing things by yourself.
So basically, I would have produced synthetic beans for these object mappers if the annotations were found on customizers as IIRC, it's not possible to return null if we want to produce a @Singleton
.
@geoand does it make sense or am I missing something?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Prior comment from some reviewer asked to remove creation of client and server instances. My quarkus mojo may not be up to the task of creating the beans as part of build.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So we don't want to create the ObjectMapper
s if they are not needed. My question was: could we create them only if they are required. I think we could do that with synthetic beans but I want to check with @geoand that this makes sense.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hum. And I'm not really sure this works because IIRC the Client writer is only initialized if the server part is not around: https://github.com/quarkusio/quarkus/blob/main/extensions/resteasy-reactive/rest-client-reactive-jackson/deployment/src/main/java/io/quarkus/rest/client/reactive/jackson/deployment/RestClientReactiveJacksonProcessor.java#L42 .
Also the JacksonBasicMessageBodyReader
that you haven't changed and should probably be changed is shared between the two.
So my guess is that this needs more thoughts. But I might be missing something as I'm not that familiar with RESTEasy Reactive.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@gsmet so basically you are asking if we can create the "RestServerObjectMapper" if there are customizers for it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@geoand so that was my initial question yes. As otherwise it's very cumbersome (especially, since you have to apply the customizers yourself).
But... my other question is: I'm pretty sure the current proposal won't work because in some cases we share the writer between client and server and if I'm not mistaken the reader is always shared.
I'm wondering if we could use @ConstrainedTo(RuntimeType.SERVER)
/ @ConstrainedTo(RuntimeType.CLIENT)
but I'm not sure it's implemented in RESTEasy Reactive.
If we can, we would make the reader/writer for client/server totally distinct and this could work.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As otherwise it's very cumbersome (especially, since you have to apply the customizers yourself).
I think it's acceptable price to pay, at least initially until we see if people actually use this feature.
I'm pretty sure the current proposal won't work because in some cases we share the writer between client and server and if I'm not mistaken the reader is always shared.
What reader and writter are you talking about?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@geoand the ones defined here: https://github.com/quarkusio/quarkus/blob/main/extensions/resteasy-reactive/rest-client-reactive-jackson/deployment/src/main/java/io/quarkus/rest/client/reactive/jackson/deployment/RestClientReactiveJacksonProcessor.java#L42
(and in the server part)
If you want to use specific ObjectMapper
s for server and client, you will need them to always be specific, right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point, I had totally forgot about that! Indeed we would need to always have both and limit them to client and server
Co-authored-by: Guillaume Smet <guillaume.smet@gmail.com>
Co-authored-by: Guillaume Smet <guillaume.smet@gmail.com>
Failing Jobs - Building 4b6d35a
Failures⚙️ Initial JDK 11 Build #- Failing: extensions/resteasy-reactive/quarkus-resteasy-reactive-jackson-common/runtime
! Skipped: devtools/bom-descriptor-json docs extensions/oidc-client-reactive-filter/deployment and 35 more 📦 extensions/resteasy-reactive/quarkus-resteasy-reactive-jackson-common/runtime✖ |
I recently came across another use case where this would be very useful, I think we should reevaluate it, WDYT @gsmet? |
Closes #23979
Provide three ObjectMappers: unqualified, client, and server that can be independently produced, customized, and injected. This allows different behaviors for the different uses.