Introduce CDI requirements for deprecated @Context injection #1340
Introduce CDI requirements for deprecated @Context injection #1340jamezp wants to merge 4 commits into
@Context injection #1340Conversation
|
I would like to suggest that the choice of calling this an entity in the first place was not necessarily helpful. It was called an entity or message body in the first HTTP 1.1 RFC but a resource in REST and in the more recent HTTP RFC it is called a resource, a representation data or a payload or message payload or message body. A lot of other frameworks, libraries or programming languages also call it a request body (as opposed to a response version). I think we should consider a better name than entity for this annotation, and not only because it clashes with JPA's Do we expect this annotation to be used to designate the response entity too? |
Yeah,
No, just on a request which is why |
|
I think, but this may be just me, I don't have data to back this up, but I think the entity term is confusing for new users. In a way that request body is not: I feel that most people understand what this is. I have some doubts about message body because I suspect fewer people associate HTTP with messages. |
|
But on the other hand, we already have |
|
Agreed for sure. IMO |
|
My personal preference would be |
|
I am leaning towards My reasoning is that we already have If we didn't already use |
|
Another option is to simply not allow CDI for resource method parameters. Then we essentially have what we have now which is no annotation on the entity. The other types that require |
As I said in my comment, the latest RFC removed entity entirely, it's not called that anymore: https://datatracker.ietf.org/doc/html/rfc9110 For some reason, they did keep entity tag but that's probably an oversight. I am not criticising IETF, I'm pointing out that nobody ever called these entities outside of Jakarta REST, and the latest RFC appears to agree with this observation. |
|
It's seems like RFC9110 uses "content" so we could use
If we really want to stick with something around entity I'd prefer |
Huh, I did not notice content when I listed all the other terms it uses. That one makes a lot of sense, given content types, content negociation… Probably not as widespread as request body for a term, but definitely a lot more obvious to anyone than entity. |
|
IMHO |
|
I did a short talk about these changes today in this PR on the Jakarta EE Futures call. @jhanders34 had a, very good IMO, idea to not allow arbitrary CDI beans to be injected into resource methods which means we would not need the Without this approach we could break compatibility and require users to add |
|
@jamezp I need to confess I somewhat got lost in the discussion. Could you please elaborate how that distinction in 5.0 and 6.0 changes anything? I am no CDI expect, so please bear with me. What problem arises from our current plan and why is that "very good IMO" idea the soltuion? 🤔 |
|
@mkarg That is a fair request and would help others too :) I'll work on something more detailed next week and work on updating this PR to reflect the plan. REST 5.0Add CDI full CDI support for resources, providers and applications for field injection and constructor injection. For resource methods, CDI will only replace the usage of Deprecate Full backward compatibility, meaning REST 6.0Remove the deprecated API's and add the |
|
Thank you, James. As in the end the result will be the same (everbody needs to overhaul his existing applications and put |
| * | ||
| * @author Marek Potociar | ||
| * @since 2.0 | ||
| * @deprecated use Jakarta Context and Dependency injection |
There was a problem hiding this comment.
Maybe we should add since 5.0 to the JavaDocs also, so people have a better understanding which version supports what technology?
There was a problem hiding this comment.
We have the version in the @Deprecated annotation. We could add it here too I guess.
| * this instance-based {@code register(...)} is not managed by JAX-RS runtime. The same registered component instance is | ||
| * used during the whole lifespan of the configurable context. Fields and properties of all registered JAX-RS component | ||
| * instances are injected with their declared dependencies (see {@link Context}) by the JAX-RS runtime prior to use. | ||
| * instances are injected with their declared dependencies by the CDI prior to use. |
There was a problem hiding this comment.
As CDI is an abstract idea but not a concrete product, shouldn't it be "...by CDI prio..." (without "the")?
| * | ||
| * @author Paul Sandoz | ||
| * @author Marc Hadley | ||
| * @see Context |
There was a problem hiding this comment.
Maybe we need another cross reference mentioned, to make clear that these interfaces are injectable?
| @Target({ ElementType.TYPE }) | ||
| @Retention(RetentionPolicy.RUNTIME) | ||
| @Documented | ||
| @ApplicationScoped |
There was a problem hiding this comment.
Actually I wonder if providers can only be application scoped, or if it was valid to make them request scoped before?
There was a problem hiding this comment.
I don't see why they couldn't be request scoped. I probably wouldn't suggest it, but I don't see why it would be an issue :)
| @Target({ElementType.PARAMETER}) | ||
| @Retention(RetentionPolicy.RUNTIME) | ||
| @Documented | ||
| public @interface EntityParam { |
| [[cdi-injection-model]] | ||
| ===== Injection Model for CDI-Managed Resources | ||
|
|
||
| When Jakarta REST resources and providers are managed as CDI beans, a hybrid |
There was a problem hiding this comment.
"When"? Isn't that mandatory now?
There was a problem hiding this comment.
We haven't defined what needs to happen with SeBoostrap which is why I added this.
|
|
||
| ====== Resource Method Parameter Injection | ||
|
|
||
| Resource methods allow for parameter injection via CDI. The method MUST not be annotated |
There was a problem hiding this comment.
The method MUST not be annotated with
@Inject
Why should someone do that? Do we really have to explicitly say that?
There was a problem hiding this comment.
The part of requiring @Inject for resource methods has been removed and we definitely shouldn't do that. My initial thought when I added it was that it would be easy for implementations to know if it was a CDI resource method or a legacy one.
|
|
||
| * **Jakarta REST-managed special parameters**: The following parameters are NOT | ||
| CDI beans and are handled directly by the Jakarta REST implementation: | ||
| ** **Entity parameter** (`@EntityParam`): The request entity body, deserialized using |
There was a problem hiding this comment.
Is there a technical reason why the entity should not be a CDI bean?
There was a problem hiding this comment.
I don't really see how it could be. You need the request to create the entity. If it was a CDI bean it would mean it could be injected into anything which doesn't have to be a Jakarta REST endpoint.
| 3. Convert the value to the target type using the same conversion rules as | ||
| specified in <<resource_field>> | ||
|
|
||
| NOTE: The `@EntityParam` annotation does NOT require a CDI producer. Entity parameters |
There was a problem hiding this comment.
I do not understand this separation. Again, I am not a CDI expert, so bear with me. IMHO @EntityParam should be provided by a CDI producer. The runtime should be that CDI producer. To produce the instance, the runtime invokes MBRs. Wouldn't that be straightforward? 🤔
There was a problem hiding this comment.
I thought about this more and I don't think it can be. We need the request to create the entity with a reader. CDI doesn't really need a request, at least not an HTTP one. We can't make it a CDI bean and assume it can just be injected let's say into a scheduled EJB.
| [[contextprovider-migration]] | ||
| ==== Migration to CDI Producers | ||
|
|
||
| Applications using `ContextResolver` should migrate to using CDI producers |
There was a problem hiding this comment.
I do not see why we need to deprecate "ContextResolver". Couldn't we instead say that runtime MUST provide CDI producers for these classes, and MUST internally invoke the original context resolver in turn?
There was a problem hiding this comment.
I've been wondering about this one as well. The ContextResolver likely doesn't need to be deprecated, so maybe we just don't deprecate which seems fine to me.
|
Thinking more about this, I'm not sure what advantage there is to allowing CDI injection into parameters. CDI beans can be injected at the instance level or in the constructor. I don't really see why we'd need them injected in resource methods. If we don't allow CDI injection into resource methods, we can keep backwards compatibility much easier. |
…otype annotations. Make the parameter annotations qualifiers. Added CDI as a required module. Signed-off-by: James R. Perkins <jperkins@ibm.com>
|
What I've done is gone with the approach of removing the The same rules apply for determining the entity in a resource method. If the parameter is not annotated with I've removed the deprecation of the I also removed the OpenRewrite recipe and will publish it elsewhere. |
Signed-off-by: James R. Perkins <jperkins@ibm.com>
instead of @context for resource injection. Signed-off-by: James R. Perkins <jperkins@ibm.com>
Signed-off-by: James R. Perkins <jperkins@ibm.com>
This PR introduces the Jakarta Dependency and Context Injection requirements as a replacement for
@Contextinjection. Note that most of this was taken from the original JakartaRest40.pdf. There are a few things I did differently however.One is I changed the entity parameter annotation from
@Entityto@EntityParam. One reason is there is already ajakarta.ws.rs.client.Entitytype and that seemed confusing to me. The other is Jakarta Persistence already has a@Entityparameter. Using@EntityParamseemed the most natural with other parameter annotations. However, I'm open to suggestions like@MessageBodyor anything else.The second is I do think we should required the
@Injectannotation on methods we want to use CDI injection on. The reason is implementations will need a way to know if we should be using CDI injection or the old way of parameter injection. For example consider a method like:We have no way to know if
MyCdiBeanis an entity or it should be handled by the CDI container.I'm opening this as a draft for now for further discussions. There are more tests that are needed for the
@EntityParamand we may need to copy some other tests to use CDI instead of@Contextinjection. I didn't want to spend too much time on that until we agreed on the rest of the PR though.This PR relates to:
We need to consider what needs to be done for #1214 and #1215 as well. I did not add any specification documentation about those as I wasn't sure where we wanted to go.
Note I added a OpenRewrite recipe here for adding the
@EntityParamannotation. However, this might be the wrong place for this. I'd initially added it here to do some testing. It needs some updating though as I changed the requirements a bit. I've left it in the draft for now, but we can remove it before we merge.