users@jersey.java.net

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

From: Marek Potociar <marek.potociar_at_oracle.com>
Date: Fri, 8 Nov 2013 12:52:56 +0100

You should simply create a method that consumes "application/octet-stream", inject HttpHeaders into one of the method parameters and check if "Content-Type" headers is present. If it is not, you are sure the request did not contain any "Content-type" headers. All requests without any "Content-type" header should get automatically routed by JAX-RS runtime to such method.

Would that work?

Marek
 
On 07 Nov 2013, at 18:36, cowwoc <cowwoc_at_bbs.darktech.org> wrote:

> 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> 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
>>>> 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?
>>
>>>>
>>>> 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
>>>> Used to insert a new element into a collection (there is no confusion about the kind of child resource being created).
>>>> 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) If so, the Javadoc should really mention that passing null is an acceptable way to omit the field.
>>
>> Thanks,
>> Gili
>