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 17:09:20 +0100

No worries Marek, I think
at least I've tried to recognize your position...Wish you did too.

I'm actually going to work on proposing to add two new properties to
Target, based on this discussion -
baseURI
prevURI

and yes - with the Target immutability being supported, I don't expect
both ones be approved - but I'll give it a go.

Likewise - more analysis of what happens after request() to follow

Enjoy the weekend
Sergey


On 02/09/11 16:49, Marek Potociar wrote:
>
>
> On 09/02/2011 04:27 PM, Sergey Beryozkin wrote:
>> On 02/09/11 14:08, Marek Potociar wrote:
>>>
>>>
>>> On 09/02/2011 01:48 PM, Sergey Beryozkin wrote:
>>>>>>> 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.
>>>>>
>>>>> I just used the names from UriBuilder, since JAX-RS 1.x users should be familiar with those names.
>>>>>
>>>> UriBuilder is a mutable one, isn't it ? That is what I'm trying to say, path().path() is associated with the state being
>>>> mutated - for me at least. You can have path() unchanged - JavaDocs will be there, but recall your argument about
>>>> revert(String, String) :-)
>>>
>>> State being mutated does not necessarily mean that objects holding the state are mutated too, e.g.:
>>>
>>> String s1 = "a";
>>> String s2 = s1.replace('a', 'b'); // s1 "state" is being mutated
>>> s1 != s2; // the instances do not mutate with the state!!!
>>
>> OK. I see what you and Santiago are saying...
>>
>>>
>>> In case of UriBuilder, the mutability wrt. URI is understandable. In case of Target it is not.
>>
>> this is due to to your position on how API should be done - I'm fine with it though. A week earlier, I'd reply 'What ?'
>> - but I'm getting a clearer picture why some design decisions have been made this or that way - not that I agree with
>> them - but I see why at least
>>
>> And I really don't see
>>> how my arguments about request(String, String) apply in this context.
>>>
>> When we talked about it earlier, I was saying JavaDocs would help to make it plain obvious that the 1st String is CT,
>> and one of your counter-arguments was that it was confusing nonetheless when looking at the code what was where...That
>> is why I referred to it when indicating JavaDocs would help to understand that path().path() is not mutable
>
> Ok, at least I understand now what you meant.
>
>>
>>> Anyway, I do understand that you are pointing out at the potential confusion. Still, I'd rather live with such risk than
>>> to change the 'path()' method name to 'toPath()', 'next()' or 'forward()'. First one is just longer, but does not really
>>> deal with the potential confusion, and the latter two ones seem just even more confusing.
>>>
>>
>> OK
>>
>>>>>>
>>>>>>> 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");
>>>>>>> library = library.path("books");
>>>>>>> library = books.queryParam("ISBN-13", "978-0451208637");
>>>>>>>
>>>>>>> I hope we can agree that A) makes more sense.
>>
>> Funny we are still talking about A& B :-)
>>
>>>>>>>
>>>>>> 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.
>>>>>
>>>>> What are you trying to say? We don't work here with strings, we work with resources and their URIs. This is not a text
>>>>> editor API.
>>>>>
>>>> I'm simply giving you my feedback. You cleverly chose the naming of Target in A) to demo the immutability and yes, the
>>>> fact we have 3 individual resources there.
>>>
>>> It's not me being clever.
>> It was a positive statement on my behalf.
>>
>>> Those 3 different URIs represent different resources. In general different URIs typically
>>> represent different resources or different resource representations or at least different contexts of the same resource.
>>> It's not a hard rule, but that's how it typically is, especially in a single-rooted URI hierarchies, which is what we
>>> are talking about.
>>>
>>>> I said that B) can also be used to reflect the actual way a user works with
>>>> the service.
>>>
>>> IMHO, anyone who would use the API as described in B is just a fool with a tool, who sooner or later will hit the wall
>>> with the code he wrote. There's unfortunately no protection against fools. We can only strongly encourage people to read
>>> some good books on designing and consuming RESTful services and the principles behind REST before using our API. Our
>>> users don't need to be REST gurus, but I think it is appropriate to assume at least a basic level of understanding of
>>> the REST problem domain. Relationship between URIs and Resources IMHO belongs to the very basic REST/ROA concepts.
>>>
>> ?
>> Just wondering why I haven't heard CXF users hitting a wall yet, given that we support the mutability...
>
> I made my comment solely in the context of our API. Perhaps, in a context of a different API, similar constructs would
> make more sense. If you in your API have a concept of a "fluid uri" that can move back and forth, fine, in such case B
> might make some sense. In our proposal, however, Target is a client side pointer to a particular resource. And that's a
> completely different concept, in which mutable URI state just does not make sense.
>
>>
>>> Sure, one can chain the path() methods and ignore the intermediate resource targets in the code, that's perfectly valid.
>>> But that does not mean that those intermediate resources were suddenly all merged into one library resource. And when I
>>> say "library resource" I mean *library* resource, not some other esoteric meaning of "library resource" expression.
>>>
>> I don;t see how the above relates to my earlier comments. Merged ? Just because a single var is used ?
>> Is this totally wrong :
>> URI lib;
>> lib = UriBuilder.fromURI(lib).path(books).path(1).build() ?
>
> Please, stop comparing apples to oranges.
>
> The purpose of a mutable URI builder is to build a URI. Any URI.
>
> The purpose of the Target is to point at a particular resource, hold configuration associated with the resource and
> provide a ways how to easily derive targets for the sub-resources, inheriting the parent resource configuration. That's
> how the concept is designed.
>
>>
>> Does it mean we have merged a /books/1 resource into a lib one ?
>
> No. It does mean, that you have used a mutable URI builder to build some URI assigned to lib variable. I don't know why
> did you decide to call the variable 'lib' as it does not make much sense to me in the context of those 2 code lines, but
> I guess you had a reason that might be visible in the larger context.
>
>>
>> Are we at the stage where we can agree to disagree :-) ?
>
> Yes. Let's do it. I can't believe I have spent so much effort in order to explain things that should be obvious from
> javadoc:
> http://jsr311.java.net/nonav/javadoc/javax/ws/rs/core/UriBuilder.html
>
>>>>
>>>>>> A is more naturally readable - but you can't get from the books section back to the
>>>>>> library entry. Which is possible with B...
>>>>>
>>>>> Are you really suggesting, that in the example A, after executing line 2 you cannot refer to the library, but in the
>>>>> (corrected) example B you can?? Are we both still talking about Java code? :)
>>>>>
>>>> I clearly said that you can't move back from
>>>> books to library - are you suggesting that is possible ?
>>>
>>> Yes, in A you still have the reference to the original library resource in the library variable, don't you.
>>>
>> Are always keeping all the variables we ever need in scope ?
>
> This is ridiculous, you can't just ignore the context of the example just to prove you are right. Btw. answer to your
> question is 'yes'. What you probably wanted to ask is "Are we always keeping all the variable *definitions* we ever need
> in scope?" The answer to that question is: 'No. Why should we? Every modern language provides mechanisms for passing
> around important variable information among collaborating execution scopes. Typically in a form of constructor or method
> input parameters.'
>
> Let's just really agree to disagree.
>
> Marek


-- 
Sergey Beryozkin
http://sberyozkin.blogspot.com
Talend - http://www.talend.com