users@jax-rs-spec.java.net

[jax-rs-spec users] [jsr339-experts] Re: Re: Re: Re: Re: Re: FYI: ResourceContext API proposed

From: Marek Potociar <marek.potociar_at_oracle.com>
Date: Thu, 6 Sep 2012 16:29:21 +0200

On Aug 31, 2012, at 5:21 PM, Bill Burke <bburke_at_redhat.com> wrote:

>
>
> On 8/31/2012 9:42 AM, Marek Potociar wrote:
>>> I'm against this feature. It appears, from the JIRA issue Marek linked
>>> to, it was mainly about supporting the injection into EJB
>>> subresources. It's not a JAX-RS concern - I agree with Bill.
>>
>> I finally found another MAJOR issue that has been closed as a duplicate
>> of JAX_RS_SPEC-72:
>> http://java.net/jira/browse/JAX_RS_SPEC-35
>>
>> Note the larger scope of the original issue. Also kindly check our older
>> discussions on this:
>> http://java.net/projects/jax-rs-spec/lists/jsr339-experts/archive/2012-04/message/17
>>
>
> Yup, my views now are pretty much consistent to my comments back then. I wasn't sure then, but we now know Java EE has a manual injection API (CDI BeanManager). So does Guice (factory), so does Spring. CDI and EJB should support JAX-RS field injections. If you want to write a pure standalone service, then pass information to constructor or method parameters of the subresource instance.
>
> Not sure about Spring, but with CDI you can even define injected beans as request scoped, so the code would be really clean in a CDI environment:

And really dependent on CDI at the moment... Unless we can agree that the JAX-RS implementations MUST support this type of JSR330-based injection even without CDI dependency, then I'm against.

One other problem I was fighting with when I was thinking about how to provide JSR 330 support which (unlike CDI) we do have in our JSR charter is that with the approach demonstrated bellow you would be injecting the sub-resource instances even in cases when you don't need them. Alternatively, you could try to inject the instance directly into the method, but in that case you're running into issue with finding out what is a sub-resource and what is entity (because @Inject applies to a method and not method param). So we would still have to provide at leas a qualifier... and once we provide a qualifier, why not to follow the existing style the users are used to and make the qualifier a full-featured injection point annotation? And then why would we need DI?

Also, another minor comment, the DRY principle is broken in your example; ideally you should not be forced to inject and set the author value manually in this case. And if you are forced to do so, it would be less error-prone to make the field final and force its initialization by providing a non-default constructor.

Marek

>
> @Path("/authors)
> public class AuthorResource {
>
> @Inject AuthoredBookResource bookResource;
>
> @Path("{author}/books")
> public BookResource getBooks(@PathParam("author") String author) {
> bookResource.setAuthor(author);
> return bookResource;
> }
> }
>
>
> @Path("/books")
> @RequestScoped
> public class AuthoredBookResource extends BookResource {
>
> @Context UriInfo uriInfo;
>
> private String author;
>
> public void setAuthor(...) {...}
>
> @GET
> @Produces("application/json")
> public List<Books> getBooks() {
>
> }
>
> }
>
> If you have a forwarding mechanism, you could write this as:
>
> @Path("/authors)
> public class AuthorResource {
>
> @Context RequestForwardingAPI forward;
>
> @Path("{author}/books")
> @GET
> public Response getBooks(@PathParam("author") String author) {
> return forward.forwardTo("/books?author=" + author);
> }
> }
>
> 1st case is you have class that is only a sub-source. 2nd case is that you have a subresource that is also a root resource. What the exact forwarding API is, I'm not sure yet.
>
> --
> Bill Burke
> JBoss, a division of Red Hat
> http://bill.burkecentral.com