users@jersey.java.net

[Jersey] Re: REST API Versioning

From: Van Klaveren, Brian N. <bvan_at_slac.stanford.edu>
Date: Fri, 25 Apr 2014 14:42:56 -0700

From a resource standpoint, it is more expensive (especially in memory starved environments).

From a development standpoint, I feel parallel deployments is the only thing that really makes sense with versioning, otherwise you end up with mixed classes, and at some point your code from v1 might was on jersey 2.4 where v2 might want to be on the new and shiny, and you end up with all sorts of classpath problems you’ll never be able to resolve.

Brian


On Apr 25, 2014, at 2:32 PM, Robert DiFalco <robert.difalco_at_gmail.com<mailto:robert.difalco_at_gmail.com>> wrote:

That's a cool approach. If I understand you correctly you are saying to keep my old version jars and just create new ones. Then have a router handle the versioning. My only issues with that are (a) more expensive on heroku (where I currently deploy) and (b) it would make hotfixes a little more tedious. But a cool idea for sure.


On Fri, Apr 25, 2014 at 2:11 PM, Van Klaveren, Brian N. <bvan_at_slac.stanford.edu<mailto:bvan_at_slac.stanford.edu>> wrote:

In the past, I have tackled this problem in several ways.

My preferred method is this:
Deploy your application to a unique path, and use an additional router or rewrite rules:

example.com/roberts-api-v1.0<http://example.com/roberts-api-v1.0>
example.com/roberts-api-v1.1<http://example.com/roberts-api-v1.1>
example.com/roberts-api-v2.0<http://example.com/roberts-api-v2.0>
example.com/roberts-api-v2.1-SNAPSHOT<http://example.com/roberts-api-v2.1-SNAPSHOT>

use a router:
example.com/api/v1<http://example.com/api/v1> -> example.com/roberts-api-v1.0<http://example.com/roberts-api-v1.0>
example.com/api/v1.1<http://example.com/api/v1.1> -> example.com/roberts-api-v1.1<http://example.com/roberts-api-v1.1>
example.com/api/v2<http://example.com/api/v2> -> example.com/roberts-api-v2<http://example.com/roberts-api-v2>
example.com/api/dev<http://example.com/api/dev> -> example.com/roberts-api-v2.0-SNAPSHOT<http://example.com/roberts-api-v2.0-SNAPSHOT>

Then the rest of the application doesn’t ever have to know about it’s version number.

I did it with the router once, using:

        <dependency>
            <groupId>org.tuckey</groupId>
            <artifactId>urlrewritefilter</artifactId>
            <version>4.0.3</version>
        </dependency>

You could also write your own filter to do something similar.

I think I had another version where I had added some HTTP headers which appended the original URL.

There’s probably better ways, but I was fine with this.

Brian


On Apr 25, 2014, at 1:59 PM, Robert DiFalco <robert.difalco_at_gmail.com<mailto:robert.difalco_at_gmail.com>> wrote:

> Let's say that I choose to do URI versioning. I know many people are against this approach but I don't want to spark a discussion on *which* method I use for versioning. I want to ask HOW I would do it.
>
> What I would like to do (ideally) is have a Container Request Filter that will see if (for example) there is a V2 contained in the incoming the request path. If there *is* the filter will look to see if there is a resource with an exact match for this path. If there is *NOT* an exact match it will modify the request URI to use the V1 version of the resource method.
>
> By doing this I do not need to create a "api/v2/whatever" version of every resource path. I will only need to modify those that differ from version 1. For example, if I have the @Path "api/user/info" but no @Path "api/v2/user/info" then the filter will remap the "api/v2/user/info" to "api/user/info".
>
> Is there a way to do this? Is there a better approach to take for URI versions with JAX-RS?
>
> Thanks.