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

[jsr339-experts] Re: Removing command pattern simplifies things

From: Marek Potociar <marek.potociar_at_oracle.com>
Date: Wed, 31 Aug 2011 11:48:30 +0200

On 08/31/2011 11:08 AM, Sergey Beryozkin wrote:
> Hi,
>
> On 30/08/11 17:04, Marek Potociar wrote:
>> Hi Sergey
>>
>> On 08/30/2011 12:53 PM, Sergey Beryozkin wrote:
>>> On 29/08/11 17:04, Marek Potociar wrote:
>>>> to do a typical GET request, which most likely will be the most prevailing use case, you SHOULD:
>>>>
>>>> - specify URI,
>>>> - specify acceptable response media types
>>>> - specify method (GET)
>>>>
>>>> With the current API proposal you can do:
>>>>
>>>> client.target(uri).request(accepted/type1, accepted/type2, ...).get();
>>>>
>>>> to me, it's as simple as it gets.
>>>
>>> Would you consider allowing for
>>>
>>>> client.target(uri).request(contentType, accepted/type1, accepted/type2, ...)
>>> ?
>>
>> I did consider it in fact, but after playing with it for a while I concluded that multiple input arguments of the same
>> type with different meaning based entirely on the order of strings (and in a vararg method) do not seem like a good
>> idea. The above example looks quite ok, but cosider a real-life usage:
>>
>> client.target(uri).request("text/plain", "application/xml, "application/json").post(item); // which is which?
>>
>> It's not very readable IMO.
>>
>
> You clipped there my comment about dropping a var support for multiple accept headers in a transitional request() :-).
> Is it really close to a common use case, having a programmatic client setting multiple accepts ?
> So what about
> request(String ct);
> request(String ct, String at);
>
> as I said your example above can be handle by using request() and then setting multiple accept headers

Varargs just add extra confusion but the problem "which is which" is there even for a method(String, String).
Additionally, as I said, content type really belongs to the part where entity is provided).

>
>> Also, I prefer keeping content type close to the entity:
>
>> client.target(uri).request("application/xml, "application/json").post(text(item));
>>
>> or generically:
>>
>> client.target(uri).request("application/xml, "application/json").post(entity(item, "text/plain"));
>>
>
> Do you really like the above ?

Yes I do :)

> client.target(uri).request("text/plain", "application/json").post(item);
>
> Seems more readable to me.

Not to me. It's perhaps a matter of taste, but I interpret the above as "Give me text or json in return for the posted
item (represented as unknown media type)".

> By the way, does one really has to use entity wrapper all the time or one of its static
> helpers, no way to set content-type freely ?
> I'm presuming the following is allowed
> inv.header("Content-Type", "text/xml").accept("text/xml").post(new Book()) ?

Yes, if you want the extra freedom, there's the Invocation you can use. The difference is that invocation does not have
named HTTP methods. It only has generic invoke/submit. Also, it does not have any header/entity mutators, but it
provides access to HttpRequest. So the above code would need to be written as:

invocation.asRequest().type("text/xml").accept("text/xml").entity(new Book()).method("POST"); // modify request freely
invocation.invoke(); // invoke the modified request

Yes, it's more verbose. But this is not the target use case of th API, although it's certainly good we provide the
flexibility for users that truly need it.

Please, kindly look at the latest version of the API and the samples. I know there have been several changes in the API
lately, but what I describe above is almost a week old stuff. To make it simpler, I just added a special example
covering the Invocation API in larger detail.

Marek