Ok, I see what you're getting at. It's not so much a question of how to represent the version to the client, it's how to manage the versions and upgrades, etc, on the server. You'd either have to carry the various versions within the same server app, or try to separate the versions into distinct apps, somehow resolving requests (whether through header param or path param, as you've indicated) to the appropriate version.
Regarding server-side version management, you may have described a good case for subresource locators. Take a look at the section toward the bottom of the page titled "Using Subresource Locators (@Path on Java method)" (http://incubator.apache.org/wink/1.0/html/JAX-RS%20Resources,%20HTTP%20Methods,%20and%20Paths.html). That specific example uses PathParam to dictate the pattern, but it could just as easily use HeaderParam. In that example, the subresource locator method has a "@Path("{userid}")" annotation on it, and the {userid} is the search criteria for which subresource to return. To use a header param instead of the path param as the search criteria, the method in your subresource locator might look like this: �...@path("/somepath") public Object findUserInfo(@HeaderParam("userid") String userId) { if(userId.equals("superuser")) { return new SuperUser(); } return User.findUserInDatabase(userId); } If we switch our thinking to versioning, maybe you could have a subresource locator method in your top level resource class. I'm not officially endorsing this methodology, but wanted to lay out the idea: @Path("/home") public class MyTopLevelResource { �...@path("/sub") public Object getVersionedSubResource(@HeaderParam("version") String version) { if (version.equals("2")) { return SubResourceVersion2.class.newInstance(); } // default to version 1 return SubResourceVersion1.class.newInstance(); } This is, of course, not the best code. To improve this I might use a SubResourceFactory that takes the version as a parameter. In that SubResourceFactory.createSubResource(String version) method, you could do a search for the class that handles the version requested, but return a default JAX-RS annotated class when the specified version class cannot be found. In this design, you could keep all your version 1 resources in a resourcesV1.jar and your version 2 resources in a resourcesV2.jar, and so on, in your .ear. I'm not aware of anyone who has an official recommendation regarding how best to manage versioning in REST. My searching came up with as many different opinions as there are people who have them. :) Anyone else have some ideas? Thanks.. mike On Sun, Apr 25, 2010 at 11:51 PM, Jason Dillon <[email protected]> wrote: > Thanks for the comments, this helps, though the choice between how I choose > to indicate the version is really more of a minor issue. What I'm still > trying to understand is how I would wire up resources/servlets/applications > to handle clients which use different versions of the protocol (the URI's + > data model for the resources). > > I suppose that if the model was versioned into packages and was compatible to > be loaded into the same classloader, then I could implement it as a webapp, > with a set of resources for the current version of the protocol, and adapting > resources for the legacy versions to convert old model into new model and > then delegate to the current version's resources. > > If the model was not compatible in this fashion I think the only option is a > webapp for each version of the model, probably still doing that > decode/delegate/encode to the current versions resources (in a peer-webapp), > or directly to an application facade if that is possible. > > I'm still trying to grok how all that would work... but basically I'm trying > to avoid having to come up with the perfect REST api in the first version > (which ain't gonna happen... I'm too anal and picky)... and to avoid having > to grandfather api turds for years and years. > > I think I understand how to use path information to handle routing requests > to versions of a resource (where the client would have to include the > requested api version in the resource uri), but I'm not sure how I would use > a header param to do that. > > So, client with v1, resource goes to /v1/resource (v1.ResourceImpl), client > with v2 goes to /v2/resource (v2.ResourceImpl). If there was just /resource > how could I use a header param to switch between v1.* and v2.* resources? > > Has anyone else tried (failed or not) to solve this problem of versioning... > ie. something I can peep at? > > Thanks, > > --jason > > > On Apr 24, 2010, at 10:43 PM, Mike Rheinheimer wrote: > >> Hi Jason, >> >> This is one of this things that could be solved ten different ways. >> For example, you could add a path parameter so that the version is >> recorded in the URI (http://example.com/version1/myresource). You >> could do it in a query param >> (http://example.com/myresource?version=1). You could do it in a >> matrix param, or a header param. >> >> For params: >> http://incubator.apache.org/wink/1.0/html/JAX-RS%20Parameters.html >> >> I think the major consideration is the decision of whether the end >> user needs to know what version they're targetting or not. If your >> end user is a web browser, and the end user needs to know whether they >> are using version 1 vs. version 2, then probably the path param, query >> param, or matrix param is the best choice. If the end user is a >> client program where the versioning is transparent to the end user, >> then perhaps the header param is the best choice for managing it. In >> the latter case, the decision of which version to use is being done at >> the application level, rather than the user level. You could more >> easily switch which version is the default in your resource if the >> decision is based on a header param that is not recorded in the URL, >> but rather in a header; client apps would need no adjustment, and you >> would not have to inform your humen end-users of the new version. >> >> That's probably the criteria I would personally use; if the end-user >> needs to see the version, then use path, query, or matrix params. If >> the end user does *not* need to see the version or the end user is a >> client application that can automatically target the version it >> requires, I'd probably use the header param. >> >> It's a good question, and one that, as with many REST practices, ends >> up having an answer of "whatever is appropriate for your particular >> needs". :) >> >> For header params: >> http://incubator.apache.org/wink/1.0/html/JAX-RS%20HTTP%20Headers.html >> >> mike >> >> >> On Sat, Apr 24, 2010 at 8:18 PM, Jason Dillon <[email protected]> wrote: >>> Just curious if there is any recommended way to handle versioning of an >>> apps REST... either from jaxrs or from winkers. >>> >>> --jason > >
