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: Thu, 01 Sep 2011 16:34:25 +0200

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.

Btw. one of the reasons why Client and Target are decoupled is that Client is supposed to do all the heavy-weight
initialization so that Target can be as lightweight as possible. Target is a "configured resource URI able to create
HTTP requests".

Marek

On 09/01/2011 03:04 PM, Sergey Beryozkin wrote:
> Thanks, that is interesting.
> Now, I don't want to sound too negative,
> Just curious...Are we are seeing a bit of over-engineering in action below ?
>
> Is that really can happen in practice, a code like that executing where, had we not had this immutability, result in
> multiple users a single shared mutable Target instance and messing things up with respect to a proper authentication ?
>
> Have to think more about Target.path() returning a new copy on the time, don't see a problem right now, accept that
> obviously I do see why you were saying no back() was needed...
> I guess, I was thinking it is handy for a current Target always know where it is now relative to the base URI, again
> based on my CXF experience, which is not possible with the current approach
>
> Sergey
>
> On 01/09/11 13:49, Marek Potociar wrote:
>> Just to clarify, target is immutable with respect to it's URI - you can update it's configuration.
>>
>> One reason was certainly to allow for easier transitions (e.g. iterations) in a URI hierarchy. Another reason was to
>> make sure that you can do easy configuration scoping based on the nested URIs:
>>
>> Target library = client.target("http://library/")
>>
>> // add common filter for adding a header with my personal library API key to all requests sent to the library service
>> library.register(new LibraryApiKeyFilter(myKey));
>> Target books = library.path("books"); // inherits API key filter
>>
>> Target myAccount = library.path("users/marek"); // inherits API key filter
>> // add the authentication filter for accessing my account resource
>> myAccount.register(new LibraryAuthenticationFilter(myCredentials));
>> Target myBooks = myAccount.path("books"); // inherits API key and authentication filters
>>
>> // everybody can access the list of available books
>> List<Book> listOfAvailableBooks = books.request("text/plain").get(new TypeLiteral<List<Book>>(){});
>>
>> // only I can access the list of my books with proper authentication
>> List<Book> listOfMyBooks = myBooks.request("text/plain").get(new TypeLiteral<List<Book>>(){});
>>
>> // this would fail with 401 or more safely with 404
>> List<Book> listOfMareksBooks = library.path("users/marek/books").request("text/plain").get(new
>> TypeLiteral<List<Book>>(){});
>>
>>
>> Marek
>>
>>
>> On 09/01/2011 02:01 PM, Sergey Beryozkin wrote:
>>> Well, that was definitely a new thing to learn,
>>> that is why you could obviously see why I typed
>>> target.accept(...)
>>>
>>> What was the rationale behind making it immutable ?
>>>
>>> Cheers, Sergey
>>>
>>> On 01/09/11 12:55, Marek Potociar wrote:
>>>> No, Target is *NOT* mutable (unlike Invocation.Builder or HttpRequest). IOW:
>>>>
>>>> Target t1 = client.target("http://books");
>>>> Target t2 = t1.path("1");
>>>> t1 != t2; // !!!
>
>