The whole point of a REST API version bump is that it is an artifact of introducing necessary breaking changes (either removing an endpoint at X path, removing Y keys, or even serializing dates in Z format).<p>Though there have been many detractors, I still think URL based versioning is the best way to go. How do you version a header on a resource that goes away or pops into existence? What if I just ask for "application/json" or the "freshest" due to ignorance and you move the target and get even fresher? There is very little practical benefit to versioning in a HTTP header except some argument about URI purity.
While this seems like a good solution, I'm not sure the problem is real: to me, a v1 API and a v2 API are two separate APIs, so the URLs for that API aren't really changing during it's lifetime (ie. the v1 stuff will stay the same for those continuing to use it). I think this is just a mis-interpretation of a core REST/web principle that the URIs for a specific resource in the API shouldn't change (hence creating a v2 or other sub-directory if you're going to change the output or functionality).
How often do you update the major version of your API ? Most of the time you can just augment your API with new end-points and keep the old paths around for backward-compatibility. When you're ready to change the major version you might as well start a new service from scratch with everything that you have learned.<p>Now that all your responses have a non IANA-approved[1] content-type, standard clients won't see it as JSON by default. Your curl requests are longer to type because you have to add this '-HAccept:application/vnd.something+json' string to your them. The reality is that bad developers will have broken clients when you update your API in any case.<p>I'm grateful that the REST movement brought attention to follow the HTTP protocol more closely but in practice, nobody writes truly RESTful clients. For that you would need to write a client that follows URLs passed in the body or in the headers. For example if you implement pagination, you're supposed to fetch page 1 and then follow the links until you're at the page you want. In reality you just make a page= attribute convention that avoids all these unnecessary round-trips.<p>[1]: <a href="http://www.iana.org/assignments/media-types/index.html" rel="nofollow">http://www.iana.org/assignments/media-types/index.html</a>
I personally prefer this approach - certainly if the changes you're making are only to the representation of your resources, then (assuming they can't be made purely additively, i.e. without breaking existing clients) simply making a new content type available seems the natural way to go.<p>If it's of interest, I wrote a couple of articles about how we implemented exactly this sort of versioning in Rails for our app's API:<p><a href="http://techblog.tribesports.com/blog/2011/09/24/versioning-the-tribesports-api" rel="nofollow">http://techblog.tribesports.com/blog/2011/09/24/versioning-t...</a>
<a href="http://techblog.tribesports.com/blog/2011/09/24/separating-api-logic-with-decorators" rel="nofollow">http://techblog.tribesports.com/blog/2011/09/24/separating-a...</a><p>I think these demonstrate the advantages of content negotiation as a versioning mechanism. To introduce a new API representation, we simply have to define a new set of decorators for our exposed resources, define a new MIME type and we're set. No monkeying with our routing, no messing around in controllers; a view-level change entails only view-level code alterations.
I like this idea a lot! I'm curious if anyone else finds major flaws in this idea but it seems to make a lot of sense to me. Yes, it may change slightly how you do your calls, but if the logic works and that's the "worse thing" that could come from this then I think it's worth implementing.
With just a bit of forethought and a little planning, an API almost never really needs to be versioned in either way. One of the problems with versioning is that it almost encourages changing the API and most consumers are slow to update, if at all.