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

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

From: Sergey Beryozkin <sberyozkin_at_talend.com>
Date: Thu, 1 Sep 2011 12:06:39 +0100

On 01/09/11 11:31, Marek Potociar wrote:
>
>
> On 09/01/2011 11:09 AM, Sergey Beryozkin wrote:
>> Hi Marek
>>
>> On 31/08/11 18:46, Marek Potociar wrote:
>>> As I said, you can iterate over path hierarchies using BFS ( http://en.wikipedia.org/wiki/Breadth-first_search )
>>> algorithm. If that's not practical, you can use DFS + stack (
>>> http://en.wikipedia.org/wiki/Depth-first_search#Algorithm_using_a_stack ). The stack can be explicit or you can leverage
>>> the implicit call stack by implementing recursive iteration.
>>>
>>> Btw. I would like to see the real life use case.
>>
>> I hope the following won't appear to be too hypothetic:
>>
>> 1. We have a base URI. We have a collection of Book IDs. We know the service allocates a unique URI to each Book using a
>> baseURI + "/" + BookID, example, http://books/1, etc. I'd like to use the client API to
>> do repetitive invocations to retrieve all or some of the Books
>
> int[] bookIndexesToRetrieve = ...;
> Target booksResource = client.target("http://books/");
> List<Book> books = new ArrayList(bookIndexesToRetrieve.length);
> for (int bookIndex : bookIndexesToRetrieve) {
> books.add(booksResource.path(String.valueOf(bookIndex)).request("text/plain").get(Book.class));
> }

Won't the above result in "http://books/1/2/3/4" say after 4 iterations
? I'm presuming that target.path() is accumulative, that is calling
target.path("1") is equivalent to
target.path("1").path("1").path("1").path("1") ?

>
> Or alternatively via path templates:
>
> int[] bookIndexesToRetrieve = ...;
> Target bookResource = client.target("http://books/{id}");
> List<Book> books = new ArrayList(bookIndexesToRetrieve.length);
> for (int bookIndex : bookIndexesToRetrieve) {
> books.add(bookResource.pathParam("id", String.valueOf(bookIndex)).request("text/plain").get(Book.class));
> }
>

I guess this should work...q

> I don't see the need for back() here.
>
This time I was more after seeing if a transition from Target to Request
can be problematic or not. It would probably help in the 1st example
(assuming I'm correct about path() being accumulative unless a template
var is used)

Repeating the same request("text/plain") is not a big deal, the flow
would see more duplications in case of repetitive posts, not a big deal
I guess too - just not optimal.

We have to repeat request(...) because of course we can't set path()
once we moved to this next request stage.

I think I'd prefer seeing

Target booksResource = client.target("http://books/{id}");
for (int bookIndex : bookIndexesToRetrieve) {
       books.add(bookResource.pathParam("id",
String.valueOf(bookIndex)).accept("text/plain").get(Book.class));
}

which could be optimized further to:

Target booksResource = client.target("http://books/").accept("text/plain");
for (int bookIndex : bookIndexesToRetrieve) {
       books.add(bookResource.pathParam("id",
String.valueOf(bookIndex)).get(Book.class));
}

This is why I liked a nearly perfect revision involving Target.prepare.
Just curious, would Entity thing work in that revision ?

Also I start thinking about the current Target to Invocation to get/etc
support being not a complete API per se but a customized API covering
basic GET/POST cases. As soon as we want to set even a basic custom
header then we are forced to move into that unfriendly
Invocation/HttpRequest world with method("GET").invoke(), etc.

But I promise, I will check the examples next :-)


>>
>> 2. Similarly to one, but using a query param.
>
> Very similar code to the above:
>
> int[] bookIndexesToRetrieve = ...;
> Target booksResource = client.target("http://books");
> List<Book> books = new ArrayList(bookIndexesToRetrieve.length);
> for (int bookIndex : bookIndexesToRetrieve) {
> books.add(booksResource.queryParam("id", String.valueOf(bookIndex)).request("text/plain").get(Book.class));
> }
>
> Again, no need for back().
>
Yes, back() would be non-appropriate here. queryParam, is it
accumulative or not ? How do we express "?id=1&id=2" ?

>>
>> I think the fluent API should be flexible enough to accommodate for repetitive invocations against the same targetURI
>> without forcing a user to retype things which are shared across requests, ex, an accept type, base URI, Content-type.
>
> It is - via path templates or via query params.
>
>>
>> Can you give me a favor and actually type some code showing how say 1 can be done, please don't hesitate to use BFS or
>> DFS techniques
>
> I didn't have to use DFS or BFS for such simple case. Give me a more complex problem! :)
>
Sounds good :-)
Sergey

> Marek


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