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

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

From: Sergey Beryozkin <sberyozkin_at_talend.com>
Date: Fri, 2 Sep 2011 11:38:18 +0100

On 02/09/11 10:41, Marek Potociar wrote:
>
>
> 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.

I may've got it wrong, as far as the concurrency is concerned. I think
though a practical code would not rely on the config demarcation
facilitated by the Target's immutability:

right, I'm here now, so lets apply this filter, now move next, hmm, may
be I should apply another filter here, actually, what user I am, is it
POST or PUT or GET ? That sounds highly unpractical to me - I'd think
how to do it at the practical level without expecting the mainline code
to *know* it all and not building this into API.

May be I'm just missing the point.

>
> Additionally, current design proves practical for traversing URI hierarchies, as shown by the iteration examples earlier.
>
Yes I can agree - you can't use a Target to glide back and forward, be a
bit more 'capable' but may be it's a bit hypothetical...

>>
>> 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?
>

OK, I'll work on it early next week

>>
>> 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".
>
OK. This looks OK. I guess I'm saying that
.path(1).path(2).path(2).path(4) does look like a classical builder
chain to me and perhaps it might be a bit confusing...Assuming you want
to keep the immutability, then may be rename path() to toPath() or
next() or forward(), to capture "from here, go there" better.


> 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.
>
A) looks fine, but a bit unusual, when I type a URI in the browser, I'm
still working with the same URI string, which I guess B) captures pretty
well. A is more naturally readable - but you can't get from the books
section back to the library entry. Which is possible with B...

>>
>> 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.
>
OK

thanks, Sergey

> Marek