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

[jsr339-experts] Re: Some comments about Target and Invocation

From: Marek Potociar <marek.potociar_at_oracle.com>
Date: Fri, 02 Sep 2011 11:41:17 +0200

On 09/01/2011 07:33 PM, Sergey Beryozkin wrote:
> On 01/09/11 15:34, Marek Potociar wrote:
>> Not sure I understand what is supposed to be over-engineered here. Different (sub)resources may have different
>> requirements. These requirements may be represented as different set of target configurations. Sometimes the different
>> requirements may be even at the level of a single request - e.g. you need to be authenticated to do PUT or POST, but you
>> can freely invoke a safe operation, such as GET. It's common use case with many existing web pages, including java.net.
>
> I can see how the idea in general, disagree it's practical to assume the immutability of URI is needed to address
> "Sometimes the different requirements may be even at the level of a single request" because it's difficult to imagine a
> case when a *single" mutable Target URI instance is shared between multiple concurrent consumers all having diff auth
> requirements. Even it's feasible, it does not warrant in itself the need for the immutability given how highly
> 'esoteric' this case is IMHO.

This is not about concurrency, this is about demarcating the configuration boundaries. Different URIs point to different
resources. Different resources may have different configuration requirements. Concurrency has nothing to do with it.

Additionally, current design proves practical for traversing URI hierarchies, as shown by the iteration examples earlier.

>
> Anyway, would you consider adding a baseURI property to Target and may be some scoped Target constructor for passing it
> from the top one ? I think it's an important Target property.

We had it there, but I removed it because I was clueless about how should we define the baseURI. If we can come up with
a good definition of Target's base URI, I don't see any problem reintroducing base URI getters for Target.

We need to keep in mind though that when it comes to relative link resolution, such base URI would be a "Default Base
URI" as defined in section 5.1.4 of RFC3986:
http://tools.ietf.org/html/rfc3986#section-5.1.4

This effectively means that the Target's base URI would not have any impact on the relative link resolution, because the
base URI would be established by using the retrieval base URI (section 5.1.3) - the actual URI of the HTTP request - or
by one of the higher precedence base URI establishing mechanism (Entity - 5.1.2, Context - 5.1.1).

>
> Having client.target("http://bar").path(1).path(2).path(2).path(4) target having no clue that the baseURI is http://bar
> seems not right.

Ok, so are you suggesting we establish the default base URI as the URI put into one of the Client.target(...) methods?
It seems reasonable. But what about client.target("http://foo").path("http://bar") ? Using absolute URI in path
overrides the original target URI. Should we also document that using absolute URI in Target.path(...) overrides also
the base URI of the returned Target instance?

>
> I don't have a real-world case to prove baseURI can be useful but I do believe it's a handy property.

I don't have problem with the base URI as such, but as I wrote above, we need to think it through. Can you please put
together a short proposal summarizing all the above into an email and ask for the EG feedback?

>
> By the way, IMHO
>
> allowing for chaining such as client.target("http://bar").path(1).path(2).path(2).path(4)
> and yet enforcing the target immutability seems non-intuitive/confusing, at least to my eye.

Consider looking at it in the following perspective:

1. Target is a link to a particular resource
2. The invocation above, in terms of resources captures a resource transition:

   client.target("http://bar").path(1).path(2).path(2).path(4)
                  R1 ----------> R2 ---> R3 ---> R4 ---> R5

So, the Target.path() tells you "from here, go there", not "change this resource into that resource".

Another example to illustrate that the resources are really different is here - consider which of the following reads
better:

A)
Target library = Client.target("http://library");
Target books = library.path("books");
Target dantesDivineComedy = books.queryParam("ISBN-13", "978-0451208637");

B)
Target library = Client.target("http://library");
Target library = library.path("books");
Target library = books.queryParam("ISBN-13", "978-0451208637");

I hope we can agree that A) makes more sense.

>
> Will double check if Invocation flow returns a new instance each time, if not then having the target and invocation
> flows combined also seems non-intuitive - however seeing no problem with it...
> Will continue my analysis

Invocation.Builder is a builder. It's mutable. Similarly HttpRequest is mutable, but it's because it's primarily
targeted at different audience - filters and handlers or some advanced power users of the client API.

Marek