dev@jsr311.java.net

RE: Container Independence

From: Jerome Louvel <jerome.louvel_at_noelios.com>
Date: Thu, 12 Apr 2007 11:51:58 +0200

Marc,

> > If you give him access to a Response object, why not also give
> > access to a
> > Request object and then why not let him directly handle the
> Request/
> > Response
> > call?
>
> You'll note that the API does exactly that ;-).

After a bit of digging, I've indeed found the WebResource interface which
has this method:

"handleRequest(HttpRequestContext request, HttpResponseContext response)"

It's not even part of the SPI package, it's in javax.ws.rs.core! :) I'm
strongly against going down this path. If the developer thinks that the
annotation based approach (with the addition of a Context injection) is not
practical for some cases, then he should directly rely on a lower-level API
such as Servlet or Restlet APIs.

That's why he should also be free to manually integrate the annotated
resources within those APIs, in order for example to implement filters,
custom authentication, custom content negotiation, etc.

This is another reason I think that having a "ContainerFactory" class and
defining an SPI are the wrong path here because it makes the developper
assume that this JSR has a complete view of the server-side Web world in
Java and that everything should be possible within its scope.
 
> I do want to make the 80% cases truly easy to implement using
> our API
> but I also think its important to have an escape hatch to implement
> the other 20%. As I wrote elsewhere, it might make sense to just
> inject some container-specific artifact to cover the 20%.

For the 20% remaining cases, I would prefer to move the discussion later in
the EG process (with the SPI discussion), or to just leave it into the hands
of implementations. Let's not try to over-control the annotated POJOs
environment, that we facilitate their integration and reuse and flexible and
maybe unexpected ways.
 
> You give the impression of wanting to define the 80% in terms
> of what
> is achievable using annotations alone. I strongly disagree with that
> - annotation driven doesn't mean annotation-only. I think developer
> productivity and ease of use is key, annotations are an important
> aspect of that but they can also get in the way if you try to use
> them for everything - sometimes a class or interface just
> works better.

I agree with this, I'm not an annotation purist. I just want to maintain a
consistent annotation-centered design. As I already said in other emails,
I'm fine with adding a couple of support classes like:
 - Representation<T>
 - Context
 - MediaType (better if in JDK directly)

> I don't see working with HTTP headers and cache control as advanced
> or edge cases, I think those are important capabilities. I
> also think
> we may disagree on what is rare sometimes, possibly due to a
> different mental model of resource classes, more on that below.

I'm fine with having a @HeaderParam annotation for example. I'm just
suggesting that this should not be the recommended way to implement Web
applications. It should be reserved to advanced cases, especially (or maybe
exclusively) when the usage of non-standard headers is involved.

> I think there may be some misunderstanding here. I've never
> suggested
> that a resource POJO (i.e. the class whose methods get called to
> service HTTP methods) wouldn't be editable, only the classes
> that map
> to HTTP entities. I think where we differ is that you seem to assume
> that there will usually be classes that map to representations
> whereas I think that resource class methods should be able to work
> directly with standard classes. I.e. I see methods like
>
> @HttpMethod
> @ProduceMime("text/plain")
> String getSomething() {...}
>
> whereas you seem to see methods like
>
> @HttpMethod
> SomethingRepresentation getSomething() {...}
>
> public class SomethingRepresentation {
> ...
> public String getValue() {...}
> }

Actually, I think that both designs are useful and likely. I probably didn't
make this view clear enough in the past. So, we should have strong support
for both of them.

> You mean something like:
>
> public MyResource {
> @Resource
> Context ctx;
>
> @Redirect("/target/{var}")
> public @Status int post(InputStream data) {
> ...
> ctx.setRedirectParam("var",somePath); // ???
> ...
> }
> }
>
> Personally I find the following much cleaner
>
> public MyResource {
>
> @HttpMethod
> public Response post(InputStream data) {
> ...
> return new TemporaryRedirect(somePath);
> }
> }
>
> I know you want to avoid classes/interfaces but in this case I think
> they really simplify things.

Here is something that I have in mind:

        @WebResource("/orders/{orderId}")
        public Order {

                @WebMethod
                @RedirectionRef("/target/{orderId}")
                public void post(InputStream data) {
                        ...
                }
        }

Of course, if finer control is preferred, we could have:

        @WebResource("/orders/{orderId}")
        public Order {

                @WebMethod
                public void post(InputStream data) {
                        ...

                        @Resource
                        Context ctx;
                        ctx.redirectPermanent("/target/{orderId}";
                }
        }

I hope this clarifies.

Best regards,
Jerome