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

[jsr339-experts] Re: [Client API] Refactoring Link and Invocation

From: Santiago Pericas-Geertsen <Santiago.PericasGeertsen_at_oracle.com>
Date: Thu, 7 Jul 2011 10:44:42 -0400

Sergey,

 I'm not convinced this is any simpler from the point of the view of the application developer. If the common case is to configure a Link with parameters, etc. (see Bill's e-mail) then your API is actually less friendly.

 Consider the following case which works with the current API:

  Link customersUri = client.link("http://jaxrs.examples.org/jaxrsApplication/customers").path("{id}");
  Customer customer123 = customersUri.get().pathParam("id", 123).queryParam("country", "US").invoke(Customer.class);
  Customer customer321 = customersUri.get().pathParam("id", 321).invoke(Customer.class);

 The reason why this works is that invocations are created behind the scenes and are used to store parameter values.

 In your proposal, you mention Link.invocable(String) as a way to create invocations. So, I think the same concepts are there, yet IMO not necessarily packaged together any better from a developer's perspective.

-- Santiago

On Jul 7, 2011, at 6:59 AM, Sergey Beryozkin wrote:

> Hi
>
> Here are some thoughts based on the current API draft and Bill's version [1].
>
> IMHO some simplification is needed. Here is the proposed list of changes:
>
> 1. Client should have factory methods only for creating Links (things that identify web service Resources). IMHO, Link needs to be named differently - but more about it later.
> ClientFactory->Client-Link is minimal and functional.
>
> ClientFactory->Client-Link and ClientFactory->Client-Invocation is the source of confusion and duplication IMHO.
>
> 2. Link must extend Configurable and HttpRequest<Link>.
> The removes the duplication between Link and HttpRequest.
> HttpRequest.Builder<Invocation> extension needs to be dropped.
> Effectively Link becomes the thing which manages the invocation itself.
> Link needs to have methods like
>
> HttpResponse get()
> T get(Class<T>)
>
> etc, as well as
>
> invoke(String httpMethod)
>
> Link is a builder (path params, queries, etc) and the final invoker.
>
> 3. Link has a single factory method for creating Invocation:
> Link.invocable(String httpMethod)
>
> I don't think it's a big problem, as far as this specific proposal is concerned, to have a String parameter given that I'm trying to make Link the central piece of API and Link will have its typed get(), etc. If needed we can have Invocation.Builder (instead of HttpRequest.Builder) introduced that will have methods like getRequest(), postRequest(), etc, returning Invocation initialized with GET, etc, to avoid confusion with Link's own get()/etc methods.
>
> 4. Invocation stays as is - it manages ***only generic invoke() and async queue()***. Invocation.Builder as suggested in 3. may get introduced at the expense of HttpRequest.Builder.
>
> 5. Link becomes the central piece of this API.
>
> 6. The only path from Client to Invocation is via Link. However, in most cases, users won't even need to do Invocation-centric programming, they will just work with Link. Invocation will only be used for async or generic invoke() cases - which would be quite specific. If really really needed Client may also implement Invocation.Builder (as suggested in 3 and 4) or a variation of it for Invocation being minimally but fully initialized from the get-go, ex, Client.getRequest(requestURI)
>
> 7. Having a dedicated AsyncInvocation looks good - but I'm quite happy with a single Invocation offering generic invoke or async options. Either option works for me.
>
> 8. I believe that what is called Link now should be renamed to WebResource or Resource or similar. WebResource acts as a "proxy", manages the interaction with remote Resources identifiled by ***links***, where links are edges as Markus said.
>
> 9. IMHO Link should act as String, unmodifyiable thing. Link should wrap:
> URI
> relation if any
> metadata if any
> base if any
> etc
>
> IMHO Link is a URI with associated metadata and that is all. If we rename what is currently called Link to WebResource then we can have
> Client.resource(URI.create("http://foo"))
> Client.resource(new Link(...))
>
> etc. Link is URI and it can be shared, passed around and will fit nicely into the whole hypermedia effort
>
> Thanks, Sergey
>
> [1] https://github.com/patriot1burke/redhat-jaxrs-2.0-proposals-rev2
>