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

[jsr339-experts] Re: Client API is very complex

From: Marek Potociar <marek.potociar_at_oracle.com>
Date: Fri, 01 Jul 2011 15:06:59 +0200

On 07/01/2011 12:20 PM, Sergey Beryozkin wrote:
> Hi,
>
> Santiago Pericas-Geertsen wrote:
>> Sergey,
>>
>> I believe that if you push all the functionality that you suggest into Client, the result is a bloated class whose
>> purpose isn't clear anymore (I think this was on the table at some point). So far the assumption has been that (see
>> bootstrapping process) creating instances of Client isn't free, and thus the separation of concerns seems sound.
>
> Well, Client is an entity which communicates with HTTP service using HTTP-centric mechanisms. IMHO, there are only 3
> things Client needs to do:
> - optionally set headers/query/etc parameters
> - ask HttpService to GET or POST/etc, providing a payload body when needed.

I agree that client is the entity managing the communication. Still I don't think the client should directly manage the
customization of the request. Put everything into one single blob just for the sake of having a single blob is not a
particularly effective design.

>
> I do not quite share a concern that having Client managing these two tasks creates an overbloated constructs which no
> one understands what it does. Prepare the invocation context if needed and get/post/etc.

It's not that no-one would understands what it does, the problem is that such design does not separate the concerns well
with a result of being less flexible and effective.

> We do it in CXF, the indications are users do use it, and I haven't had yet anyone complaining about the complexity of
> CXF JAX-RS client API or being limited (except that we don't do async support yet)

I'm afraid that "CXF JAX-RS client API" is an oxymoron :) It's either CXF or JAX-RS. Anyway, let's stick to the
technical discussion rather than arguing about what Jersey/CXF/Resteasy client API users complain or not complain about.

>
> ClientFactory has to manage the 'non-free' bootstrapping process. In the current version we have a long chain of
> factories. ClientFactory creates the Clients and a given Client cheaply works from them on.

ClientFactory is just a common, standard entry point to the API. All the real bootstrapping should happen in the client
instance at the creation time. We need to keep this in the client so that the different requirements on versioning and
client implementation remain satisfiable in the containers with multiple running applications.

>
>
>> Client, Link and HttpRequest/Invocation have clearly defined roles in the API. The HttpRequest/Invocation pair exists
>> so that handlers and filters can work on HttpRequest instances that are not invocable.
>>
>
> Please, explain me in leyman terms what is Client and what is Link

Client is the place where all the heavyweight initialization happens. It is also the place holding the common
configuration. It§s responsibility is to manage the communication infrastructure and create the lightweight objects,
such as invocations and links. Client does not have any relationship with a particular resource.

(Resource) link provides an "access" to (or an identification of) a particular resource the user wants to work with.
User can use a resource link to specify a resource or domain-specific configuration, derive links to sub-resources or
create invocations targeted at linked the resource.

Invocation represents a single HTTP invocation, targeted at a particular URI (resource). An invocation enables
construction of the underlying HTTP request (entity, method, headers...) as well as support for further customization of
a single invocation configuration (e.g. security, logging etc.). It also provides support for batched request execution
using a command pattern.

All of the above should be obvious from the proposal wiki. If it's not, please point me to the parts, that are missing
in the proposal.

Marek

>
> Thanks, Sergey
>
>> -- Santiago
>>
>> On Jun 29, 2011, at 8:37 AM, Sergey Beryozkin wrote:
>>
>>>>>> 3. Link **is** effectively a Client even though Links are supposed to be identifiers of resources Clients are
>>>>>> supposed
>>>>>> to work with.
>>>>> I did have this design at one time, but then I got a feedback that I am missing the instance to hold expensive
>>>>> initialization.
>>>>>
>>>> The current Link abstraction is very nice because you can configure things like security for a specific resource
>>>> that you are going to invoke on more than once. YOu can also pass Link references around without also having to
>>>> worry about passing Client references as well.
>>> My major concern is that overall it is complex. Too many factories.
>>> Link is a Client and IMHO, despite the fact it may sound controversial, Link is 'over-engineered' and redundant, as
>>> far as its role of creating invocable HttpRequests is concerned.
>>>
>>> IMHO
>>>
>>> Client must be the thing which manages the invocation and Client is the entity which drives it and Client. Client
>>> must be able to act as a builder. By implementing Invocable or similar it can be passed around and consumed by
>>> generic executors.
>>>
>>> Client will have get()/post() and friends and it will be simple and easy to understand - client will GET something,
>>> client will POST something to a resource URI/Link.
>>>
>>> Client will have a method such as toInvocable(String httpMethod) or similar so that it can be optionally converted to
>>> Invocation and queued if needed.
>>>
>>> Client will act as a builder and be able to spawn new Clients for dealing with subresources. If Client needs to move
>>> away to a new absolute URI then ClientFactory can cheaply create a new Client.
>>>
>>> Dynamically adding features to existing Clients is complex and makes it difficult to make an injected Client
>>> reference thread-safe.
>>>
>>> ClientFactory manages expensive initialization and such.
>>>
>>> I'm worried about users being forced to write a generic invocation code
>>>
>>> Sergey
>>>
>>>
>>>
>>>
>>
>