users@jersey.java.net

[Jersey] Re: Specifying different sub-resources depending on the Content-Type?

From: Cameron Heavon-Jones <cmhjones_at_gmail.com>
Date: Tue, 21 Jun 2011 15:48:41 +0100

On 21/06/2011, at 2:03 PM, Gili wrote:

> On 21/06/2011 6:34 AM, Cameron Heavon-Jones [via Jersey] wrote:
>> Isn't this the case between implicit vs explicit versioning? Implicit versioning is evolution by only adding new information, whereas explicit versioning allows for revolutionary changes.
>
> That's correct. I lean more heavily than most people towards breaking backwards-compatibility if there are major gains to doing so. Worse case scenario, I keep version at 1.0 forever. It's there to protect me.
>

good justification :)

i'm leaning the other way, but maybe that's because i'm (foolishly?) relishing the challenge of producing an evolving api :)


>>>> This can be enforced as you showed through created new methods with consume\produce annotations, but since there will always be a device with id=5, and no duplicate ids, i'm not sure what you're really accomplishing if this is just to return data?
>>>
>>> Because each subclass contains different fields, I need to issue different database queries to retrieve the data (remember, each subclass is mapped to a different table).
>>>
>>
>> Isn't there a polymorphic load available with multiple table persistence? I seem to remember doing something similar in hibernate years ago, something like:
>>
>> MySpecifcClass obj = session.load(MySpecifcClass.class, id);
>
> I'm using straight JDBC, but yes I could implement this as well. The point, though, is that if the user requested Android #43 and item #43 happens to be a blackberry I want to return an HTTP 404. I can either have Jersey select different codepaths for me which would implicitly know the expected type, or I could handle this in a single method which checks the Content-Type and Accepts header manually. I prefer smaller methods to the use of a large method containing a switch-statement.

one thing i would point out is that you're never going to return a 404... jersey will produce a 415 - unsupported media type. not much difference tho.

>> To continue the dispatch process on a new sub-resource you have to use what is called a "sub-resource locator" which is essentially a @Path annotation on it's own - it can't have any http method annotation.
>>
>> You *might* be able to have a @Consumes or @Produces, but i'm just not sure... maybe someone from jersey team can confirm?
>>
>> if you can, then you should be able to do this, which is exactly what you want, no?
>>
>> @Path("id")
>> @Produces(ANDROID_TYPE)
>> public AndroidDevice getAndroid(@PathParam("id) String id){
>> return new AndroidDevice(id);
>> }
>>
>> @Path("id")
>> @Produces(IPHONE_TYPE)
>> public IPhoneDevice getIPhone(@PathParam("id) String id){
>> return new IPhoneDevice(id);
>> }
>
> That would work for @GET, but what about @PUT, @POST, @DELETE which need to @Consume? I'm expecting to be able to declare a single method at the parent resource for all these http methods.
>
> Gili



I thought you might want to consume some additional types in the subresources, but since it's all json i guess not.

it all works the same as long as there's always an "Accept" with the correct media type.

the Consumes is kind of redundant on the parent resource as a result, it might even throw out GET requests which have no content if there isn 't a Content-Type header.

cam