users@jersey.java.net

[Jersey] Re: Jersey2: Impossible to POST with empty entity?

From: cowwoc <cowwoc_at_bbs.darktech.org>
Date: Thu, 07 Nov 2013 12:36:24 -0500

Marek,

     Below, you proposed I migrate from

@POST @Consumes("terminal") /companies/5

to

@POST /companies/5/terminals

     I just discovered a problem with this approach.

     According to http://stackoverflow.com/a/14879077/14731 if version 1
of my API doesn't require a Content-Type (since the request body is
empty) but version 2 adds a Content-Type and request body, then I have
no way of controlling which method version 1 get routed to. There is no
way to specify @Consumes for the case with no Content-Type.

     Either @Consumes needs to support matching a non-existent
Content-Type, or I am forced to specify a Content-Type for an empty
body. In the latter case, you need to modify the Client API to let me
pass a Content-Type for requests without a body.

Gili

On 07/11/2013 11:46 AM, cowwoc wrote:
> On 07/11/2013 11:16 AM, Marek Potociar wrote:
>>
>> On 07 Nov 2013, at 16:41, cowwoc <cowwoc_at_bbs.darktech.org
>> <mailto:cowwoc_at_bbs.darktech.org>> wrote:
>>
>>> Hi Marek,
>>>
>>> Are you proposing adding the necessary API methods but throwing
>>> RuntimeExceptions unless some flag is set? I would support this
>>> approach, although in practice I don't think you'll need such a flag
>>> because we're talking about legal requests. Whether a request is
>>> "legal but non-sense" is a subjective matter.
>>
>> What I'm thinking is to make a flag (which could be by default
>> enabled in the Jersey test client and) that would make sure Jersey is
>> not trying to remove any headers. (Even though in this case I think
>> we have a different problem - look at the post(...) method javadoc
>> and the sentece about overwriting Content-* headers; there is also a
>> related bug filed on that already, IIRC).
>
> I see the problem (Content-* headers) but perhaps we can exploit a
> hole in the specification. If the entity does not provide a
> Content-Type then there is nothing to set, hence no overwriting takes
> place.
>
> PS: I couldn't find the relevant bug report. Where is it?
>
>>
>>> To prove my point, I'll provide you with specific examples for the
>>> use-cases I was inquiring about:
>>>
>>> * POST with a Content-Type but no body
>>> o When a parent resource may be used to create different kinds
>>> of child resources, the Content-Type is used to specify
>>> which kind of resource to create.
>>>
>> That is not very RESTful. Representation should not drive the
>> resource "type".
>
> Where does it say that?
>
>>> o
>>>
>>>
>>> o Example
>>> + Create a new "terminal" by invoking POST /companies/5
>>> with Content-Type: application/vnd.company.terminal
>>> + Create a new "expense report" by invoking POST
>>> /companies/5 with Content-Type:
>>> application/vnd.company.expense-report
>>>
>> Yuck! I certainly would not want to support the above, or make it any
>> easier to support that. If you want to create new resources like
>> this, you should better design a separate "collection" URIs for that
>> - /companies/5/teminals , /companies/5/expense-reports
>
> I think I can make this change, but I don't think it's right for
> Jersey to be opinionated. The REST community has many different
> opinions on the "right way" of doing things. If we're going to start
> eliminating functionality based on individual opinions we're going to
> anger a lot of users.
>
>>> * POST without either a Content-Type or body
>>> o Used to insert a new element into a collection (there is no
>>> confusion about the kind of child resource being created).
>>> o Example: Create a new "transaction" by invoking POST
>>> /transactions: http://stackoverflow.com/a/147299/14731
>>>
>> This is doable, right?
>
> I'm not sure. Are you expecting me to pass null into entity or
> MediaType in this method?
> https://jersey.java.net/apidocs/snapshot/jersey/javax/ws/rs/client/Entity.html#entity(T,
> javax.ws.rs.core.MediaType)
> <https://jersey.java.net/apidocs/snapshot/jersey/javax/ws/rs/client/Entity.html#entity%28T,%20javax.ws.rs.core.MediaType%29>
> If so, the Javadoc should really mention that passing null is an
> acceptable way to omit the field.
>
> Thanks,
> Gili