While there are many right ways to version, there are also a few wrong ones. Like putting the version in a header.
While there are many right ways to version, there are also a few wrong ones. Like putting the version in a header.
I'm sure that's specified somewhere, but it's a shamefully stupid specification, so don't follow it. Any sane person reading that is going to think you're accepting a specific version of JSON.
Also, if you must put versions be in a header, STOP with the nonsense of pretending things don't exist. Give us some freaking clue, return a 404 and explain that we're missing your stupid header, or that the planets haven't aligned, or whatever we're supposed to fix.
* Have to set up response headers and caching carefully to make sure different versions are cached separately.
* A bit of extra complexity to set up load balancing.
* A bit of extra complexity to set up web framework routing to controllers.
* A bit of extra complexity for logging to track which endpoints were called.
* Calling the URL without specifying a version gets you some undefined version...
* ... or if you require a version header, can't preview GET endpoints in a standard browser.
* If different parts of the API have different latest versions, you can't encode it in an URL and therefore can't return URLs for linking between resources.
* On major version changes you might be removing, renaming or moving URLs, so why keep them pure and versionless in the first place.
The complexity of dealing with headers seems easier than the complexity of routing constantly changing urls.
How often are your APIs changing incompatibly anyway?
When they do changing the URL should dwarf next to changing the surrounding code to the new data model. If that's not the case then what was the point of the upgrade?
"...it will be much easier to run analytics on usage from web access logs..."
Headers don't normally get logged the way that URLs do. Having easy and cheap analytics is very helpful in making the right calls. "Expensive" analytics is really painful with APIs because some people rightfully get scared about the impact of making changes while others will just plow ahead.
We need to strive to make an API obvious and "immutable" (i.e. under one path you get one specific behavior). This in affect means the good old boring /v2/ in the URL path tends to be best if you can't keep everything under one roof by deprecating/removing/introducing single endpoints in the initial version (due to lots of name collisions).