Hi Sergey,
I don't want to sound arrogant, but it's not that I took the first API design that popped up in my head and pushed
strong for standardizing it. I spend long hours going back and forth considering all the EG suggestions, trying
different approaches and evaluating the PROs and CONs. At one point I did consider the "floating" Target idea too. But
in the end it did not seem the right design choice. Disregarding some of the technical objections for now, the purpose
of the API is to enable building non-human web service clients after all. Those clients have very different
characteristics from human clients. They are typically programmed (by humans) to do specific tasks with specific web
services, not to browse merrily back and forth exploring the web on their own. After all, programmatic clients don't
have the ability to interpret arbitrary response data the way humans do. At least not yet. That's why I find the less
"fluid" design preferable when it comes to low-level API.
Marek
On 09/08/2011 05:50 PM, Sergey Beryozkin wrote:
> OK, lets just drop it. Not sure yet if I'm disappointed or not.
> I guess what seem like naturally useful properties to me is hard to add with those possible issues to do with
> stacks/lists/possible leaks. I accept though developers can live without the explicit support.
>
> One thing I'd encourage you to do is, without any commitments, try and prototype during a spare hour or so :-) another
> version of API, the one which would attempt to approach it all with the assumption that this API represents a consumer
> exploring the RESTful application, capture the usual browser experience.
>
> I know we are doing it for developers to write the code - but I'm thinking that ideally the api would capture somehow
> the way the user works because it a typical way a restful application is explored.
>
> The current API is strong in its own way - just feels a bit procedural to me, as far matching that user experience is
> concerned.
> Sorry if I sound unclear or academical, etc :-), just wanted to express that - who knows - may be API can still be moved
> forward somehow
>
> thanks, Sergey
>
> On 08/09/11 13:09, Marek Potociar wrote:
>>
>>
>> On 09/08/2011 11:24 AM, Sergey Beryozkin wrote:
>>> Comments inline,
>>>
>>> On 07/09/11 14:22, Marek Potociar wrote:
>>>>
>>>> So, can you please share the examples you have in mind?
>>>>
>>>
>>> Well, I've been thinking about cases where at a certain point in the application path a decision is made, based on say
>>> the GET response or certain HTTP error status, that the alternative route having the same origin as this current route
>>> has to be tried.
>>> In this particular case we can get an origin passed along all the time - possible. However if we generalize the problem
>>> a bit and say we want
>>> a method like go(Target) do roam around and revert back to the prev segment, or may be to the origin, or may be two
>>> segments back, all in order to retry, then we'd probably have to code to pass a stack of Targets along.
>>> Also allows for an alternative impl of the iterations...
>>>
>>
>> The first use case does not apply to target's base URI, since anything in the response is resolved using the URI of the
>> request. The target's base uri gets never considered.
>>
>> Second use case realy does sound academic and most likely can be 100% covered by existing API with a slight change in
>> the approach to the implementation.
>>
>>> np if the above sounds a bit academical or non-practical. I'm not sure, there's no 'glue' between various Targets,
>>> probably simplifies things at the impl level.
>>>
>>>> What do you mean when you say "property"? Static method?
>>>>
>>>
>>> Meant that Target class would have getter and setter for a baseTarget property
>>
>> Ok, I understand now.
>>
>>>
>>>> So, just to make sure we are on the same page, what would be the value of "uri" in the following example?
>>>>
>>>> URI uri = client.target("http://service").path("1").path("2).path("3").prevTarget().prevTarget().getUri();
>>>>
>>>> My point is that the code above demonstrates the need to use a stack to implement prevTarget() properly. And the
>>>> problem
>>>> I see is that you need to use this stack even in the 99.9% Target use cases where the method is not needed. Not to
>>>> mention that the stack can grow pretty much indefinitely.
>>>>
>>>
>>> In the above we have t1, t2, t3 and t4 targets, where t1 corresponds to client.target("http://service"), etc.
>>>
>>> Here is the links, the way I see them:
>>>
>>> t4 -> t3 (prev)
>>> t4 -> t1 (base)
>>>
>>> t3 -> t2 (prev)
>>> t3 -> t1 (base)
>>>
>>> t2 -> t1 (prev)
>>> t2 -> t1 (base)
>>>
>>> t1 -> null
>>> t1 -> null
>>>
>>> Looks like a linked list to me...
>>
>> Reverse linked list with appending to the end (or linked list with insertion at the beginning) = stack :)
>>
>> In any case, the problem with keeping the (most often unnecessary) creation history data all the time remains.
>>
>> Marek
>>>
>>>>>
>>>>> I'm concerned I'm seeing the immutability showing its other side here...It allows for doing the explicit dynamic
>>>>> configuration of Targets in the code - which IMHO does not belong to the application layer at all - but presents a
>>>>> challenge to introducing properties
>>>>> which IMHO could be explored at runtime dynamically...
>>>>
>>>> I am not sure I follow the above. Can you please be more specific?
>>>>
>>> I was referring to the possible difficulty associated with adding those props (possible leaks ?, etc) which is a
>>> side-effect of having the immutability in place...Immutability does have it pluses, and for me that would probably be
>>> sharing a single Target across multiple threads (not sure yet what would happen there in case of template vars being
>>> used in the Target path)...
>>>
>>> Anyway, I'm kind of easy now on having this properties added or letting the developers deal with them if needed
>>> Sergey
>>>
>>>> Marek
>>>>
>>>>>
>>>>>> Anyway, if you still feel strongly about this proposal, please open a new Jira issue to track this RFE too.
>>>>>>
>>>>> Lets see if it's worth it...
>>>>> Sergey
>>>>>
>>>>>> Marek
>>>>>>
>>>>>>> This makes Target a more 'capable' and allows for tracing all the intermediate Targets. To some extent this can be
>>>>>>> compared to UriInfo.getMatchedURIs property...
>>>>>>>
>>>>>>> Rules:
>>>>>>>
>>>>>>> All Targets created from absolute URIs must return null;
>>>>>>> Those created from Target.path(relativePath); return the previous Target.
>>>>>>>
>>>>>>> Examples:
>>>>>>>
>>>>>>> Target t = client.target("http://service");
>>>>>>> assertNull(t.getPrevTarget());
>>>>>>>
>>>>>>> Target t2 = t.path("2");
>>>>>>> assertSame(t, t2.getPrevTarget());
>>>>>>>
>>>>>>> assertSame(t2, t2.path("3").getPrevTarget());
>>>>>>>
>>>>>>>
>>>>>>> Comments ?
>>>>>>> Sergey
>>>>>>>
>>>>>>> [1]
>>>>>>> http://java.net/projects/jax-rs-spec/sources/git/content/src/jax-rs-api/src/main/java/javax/ws/rs/client/Target.java?rev=bdee7808db117198b8e611551a12a099bcf6b103
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> Cheers, Sergey
>>>>>
>>>>>
>>>
>>>
>
>