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

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

From: Marek Potociar <marek.potociar_at_oracle.com>
Date: Tue, 30 Aug 2011 18:04:12 +0200

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. 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"));

Marek

>
> (cases involving multiple accepts can be addressed via request())
>
> so that another typical case involving post can be addressed ?
>
> client.target(uri).request(contentType, accepted/type1, accepted/type2, ...).get()
>
> is possible which is not very cool - but one can do the same with request() too.
>
> having options for
> client.target(uri).request(contentType, accepted/type1).post(entity)
> and
> client.target(uri).request(accepted/type).get()
>
> is appealing to me
>
>
> Sergey
>
>
>
>>
>> And what if one wants to send a HTTP GET without the accept headers? No implementation would object to:
>>
>> client.target(uri).request().get();
>>
>> But why the extra verbosity in this case? Well, IMHO, that's not what one SHOULD do. It is OK for the API to slightly
>> push you in th right direction. And it's also OK, if such use case is more verbose that it could be.
>>
>> But what about the the (post)/put/delete? Admittedly, those do not necessarily need the extra request() and are somewhat
>> a victim of the design decision about the interface inheritance. But since those are expected to be used less often, I
>> guess an extra .request() is tolerable.
>>
>> I have to confess that advocating any side in this particular case is difficult for me. I see the point in what Bill and
>> Santiago say about SoC and I see the practical side you and Markus are appealing to. I have opted for a compromise
>> solution that would make the most prevailing simple use cases (GET/POST) as simple as possible[*] while respecting the
>> SoC argument.
>>
>> Marek
>>
>> [*] assuming we are considering the correctly formed requests with the accept header present
>>
>> On 08/29/2011 05:21 PM, Sergey Beryozkin wrote:
>>> On 29/08/11 16:12, Bill Burke wrote:
>>>>
>>>>
>>>> On 8/29/11 11:04 AM, Sergey Beryozkin wrote:
>>>>> Just few days ago you were all explaining to Bill how important it was
>>>>> to keep users happy
>>>>
>>>> Its funny because I've been trying to do the exact same thing: explain
>>>> how important it is to keep users happy. A API design that makes sense
>>>> and is self-documenting creates a lot of user happiness.
>>>>
>>> LOL :-)...
>>> I'd say as a user I want to see
>>>
>>> target.path(...).header(blah).get();
>>>
>>> get() *is* a request. Thus request().get() is a duplication. The transition may look better at the interface level - but
>>> no so at the user level (at least to me). The problem is request() is only there to address the case which most of users
>>> like me won't deal with.
>>>
>>> apologies if I sound like a broken record :-)
>