jsr339-experts@jax-rs-spec.java.net

[jsr339-experts] Re: Low-level JAX-RS client API proposal

From: Marek Potociar <marek.potociar_at_oracle.com>
Date: Thu, 12 May 2011 17:32:52 +0200

On 05/07/2011 06:04 PM, Markus KARG wrote:
> Marek,
>
> looks promising so far, but as it is a rather lot of classes and methods you possible might have expected correctly already that I will have a lot of comments to post... ;-) So here they are.
>
> * As we are heavily using Java EE, we are running our clients in Java EE Application Client Containers, and the web resource is located in the same domain's server container. So it is very annoying that the client application must provide the URI of the web resource. With JAX-WS it gets the end point injected. It would therefore be really good to get injected a WebResource into the client. Handling of the Client must be provided by the Java EE Application Client Container in that case. For Java EE Fat Client vendors this would be a highly appreciated feature, which got already discussed between Paul Sandoz and the Java EE team AFAIK. This certainly enforces that a Java EE compliant Application Client Container MUST provide an implementation of the JAX-RS Client API. Obviously it makes sense to extend this to all Java EE containers, as any Java EE component could be a client in turn.

I wonder what would be the type of the injected instance. In JAX-WS it's obviously the typed web service proxy since
JAX-WS is an RPC based architecture. But what are you suggesting to be injected in the case of a RESTful API?

Do you have in mind something like:

@Path("somePath")
MyResource { ... }

MyClient {
   @ResourceRef(MyResource.class) WebResource resource; // URI calculated automatically
   ...
}

?

>
> * How to install custom providers (MessageBodyReader, MessageBodyWriter, ContextProvider, ExceptionHandler)?

Added a comment to the spec writing task #81. Spec should cover this.

>
> * Reverse exception handling (i. e. transforming 404 FileNotFoundException etc.) seems to be not possible, but would be great. Just as a server can turn FileNotFoundException into 404 by pure declaration of a provider, it should be possible the reverse way on a client.
>

Added a subtask for this: #100

> * Why not having a Client.create(Class) or Client.create(Class, String method) way to create WebResource? This would allow to obtain URI information from annotated ResourceClasses. That way a vendor could provide a JAR with those to the client application developer reducing the need to know the pattern of the URIs. This is particularly useful if server and client application are implemented by the same team, as it might be the case for in-house applications. Obtaining the correct URI pattern is a real pain with JAX-RS 1 currently, so this could be rather useful.

Added subtask #101

>
> * Support for HTTP/1.1 sessions: I did not find information in the JavaDoc how an application can tell whether a HTTP call shall run in the same or in a different HTTP/1.1 session against the same WebResource (since WebResource is not called WebResourceSession, I expect that it handles sessions internally).

Is that something you would need in a RESTful API? What would be the use case?

>
> * Client Side Caching, see separate discussion in this forum.

Ehm... :)

> * Why not splitting the actual Client from the ClientFactory to make clear the different use cases (creating a Client vs. creating a WebResource)? Also, instead of using delegates, we could provide a ClientProvider class that creates ClientFactories. This makes more clear to the user what class is for what use and it allows to reduce the spec on the level of interfaces while currently the Client class contains actual implementation code.

That's something I also wanted to look at. I have added a subtask #102

>
> * JavaDocs do not explain how a caller should know the name of a Feature or a Property. Either the property names should be told, or it should be told that this information is provider specific. Also it is unclear, what Properties and Features are good for particularly at ClientRequest and ClientResponse -- what are those good for?
>
> *JavaDocs of Client.resource() says "Creates a Web resource", which is misleading, as it does not create a Web resource. It creates an instance of the WebResource class, which is nothing but a connection handle TO a Web resource. Users could expect that method to do HTTP POST, which it actually doesn't do.
>
> * For me it is not clear whether ClientConfiguration is allowed to be implemented by a calling application, since the JavaDocs only mention modification of an obtained default configuration. JavaDocs should clear tell whether this is allowed or forbidden.
>
>
> * For me it is not clear why there are both, getClasses and getSingletons to get providers. On the server side, getClasses returns resources, and getSingletons returns Providers. But how does that work on the Client? What is the intention of providing two ways of providers? Since both must not be null, it looks like one has to provide an instance AND its class, but the class can be obtained from the instance in turn. So what is getClasses good for actually?

Added all of the above to a special "fix javadoc" task #103 (although the last comment may result in something more
eventually).

>
> * I'm not a big friend of abstract classes since it reduces the freedom of the provider. Why not just providing an interface for ClientFilter? I doubt that anybody is unable to write that single code line that keeps the "next" reference. Also, as a WebResource is only to be created by a builder and the builder is to be provided by a JAX-RS implementation, I do not see a need to provide more than the WebResource's interface as part of the spec. It should be completely up to the implementation how WebResource works internally and what it extends from.

This is going to be redesigned as part of the task #99.

As for the interface vs. abstract class, I prefer interfaces too, but we need to understand that there is a serious
limitation: you cannot add new methods into an interface in a future release without breaking BW compatibility.

>
> * I'm not a mathematical expert, but WebResourceBase's .hashCode() implementation looks rather complex. I think "return this.getClass().hashCode() ^ this.uri.hashCode()" would do and would be much simpler? Looks like some black magic currently. ;-)
>

Me neither, that's why I used my IDE to generate it for me. I would be happy to change it if you can prove that your
version provides a widely spread hash codes :)

> * Why naming it "ClientFilter"? I expect that JAX-RS providers server filters too and I do not see a need for a making a difference in both, as both handle requests and responses. We could share the same interface for that.

Good point, will consider it as part of task #99

>
> * JAX-RS 1 is able to detect providers automatically. The JavaDocs do not say that a client will do so. Why?

Added to #103

>
> * Why insisting on ClientRequest being Cloneable?

Since it seems we will have a fully mutable request, to be able to reuse a preconfigured request in multiple
invocations, having it cloneable may come handy IMO.

>
> * Is it essential to keep the ordering of cookies? If not, why then returning List<NewCookie> instead of just Collection<NewCookie>?

Is there any signinficant advantage behind that generalization? List provides more manipulation methods compared to
collection. How about Set?

>
> * It might happen that a client does not know the entity type a server is sending. It then will inspect the Content-Type header to know the MediaType. But when it wants to get the entity as a JAXB instance, how shall it know the Class to provide to ClientResponse.getEntity(Class)? To solve that it would be good to have ClientResponse.getEntity() method that just doesn't expect to get a Class, and which just returns the Object instance created by the particular MessageBodyReader.

Good point. Added as a comment to a new task #104

>
> * Can you provide a use case when a user will apply the ClientResponse.bufferEntity() method?

E.g. you want to execute XQuery on the returned XML stream?

>
> * The current proposal seems to expect that a WebResources get filtered ever or never, but it might be the case where filtering is dependend of the current session. So the question is where we need to support that. Currently it won't work as removing a filter while an asynchrounous request is pending might lead to unknown behaviour.

Can you share the use case in particular? I am confused by the notion of the session - I thought we are shooting for a
stateless API.

>
> * I am the maintainer of the WebDAV package for JAX-RS and so I am heavily interested in providing a WebDAVMethodInvoker as a replacement for the HttpMethodInvoker. But I did not find a way how a calling application could register interest is that. How to do that?

So basically you want something like unwrap(Class<T> clazz) on a web resource?

>
> * A GUI might be heavily interested in getting updated after receivering another HTTP chunk. I didn't find a way how an application could register for such events. This is essential to show a progress bar with long-lasting downloads.

Let me have a look at that - added new subtask #105. But it seems to me that this is something that should be done at
the transport layer.

>
> * Side note: My Eclipse shows a lot of warnings. Style should be fixed in the final release.

So does the checkstyle plugin configured for the project :) Let's worry about that little bit later though.

Thanks again for a lot's of useful insights!

Marek

>
>> -----Original Message-----
>> From: Marek Potociar [mailto:marek.potociar_at_oracle.com]
>> Sent: Dienstag, 3. Mai 2011 18:46
>> To: jsr339-experts_at_jax-rs-spec.java.net
>> Subject: [jsr339-experts] Low-level JAX-RS client API proposal
>>
>> Hello experts,
>>
>> I have just published the low-level client API proposal page[1] on our
>> project wiki. I have also pushed the initial
>> client API code (including javadoc) to the public git repository.
>> Please consider it to be an initial draft to start the
>> EG discussion that should lead to the final proposal.
>>
>> The proposal wiki page[1] summarizes what has been done so far. It also
>> lists some open questions we are aware of that
>> still need to be addressed. Thanks to Santiago the page also contains
>> an UML class diagram of the initial API classes as
>> well as pointer to the client API samples wiki page[2].
>>
>> Please, read through at the proposal wiki page, look at the sample
>> usages, checkout the source code and browse through
>> the javadoc to familiarize yourselves with the proposal. We are looking
>> forward to your feedback!
>>
>> Let the fun begin, :)
>> Marek
>>
>>
>> [1] http://java.net/projects/jax-rs-spec/pages/Low-levelClientAPI
>> [2] http://java.net/projects/jax-rs-spec/pages/Low-
>> levelClientAPISamples
>