What is the best way to version REST URIs? Currently we have a version # in the URI itself, ie.
http://example.com/users/v4/1234/
for version 4 of this representation.
Does the version belong in the queryString? ie.
http://example.com/users/1234?version=4
Or is versioning best accomplished another way?
I would say making it part of the URI itself (option 1) is best because v4 identifies a different resource than v3. Query parameters like in your second option can be best used to pass-in additional (query) info related to the request, rather than the resource.
Ah, I'm putting my old grumpy hat on again.
From a ReST perspective, it doesn't matter at all. Not a sausage.
The client receives a URI it wants to follow, and treats it as an opaque string. Put whatever you want in it, the client has no knowledge of such a thing as a version identifier on it.
What the client knows is that it can process the media type, and I'll advise to follow Darrel's advice. Also I personally feel that needing to change the format used in a restful architecture 4 times should bring huge massive warning signs that you're doing something seriously wrong, and completely bypassing the need to design your media type for change resiliance.
But either way, the client can only process a document with a format it can understand, and follow links in it. It should know about the link relationships (the transitions). So what's in the URI is completely irrelevant.
I personally would vote for http://localhost/3f3405d5-5984-4683-bf26-aca186d21c04
A perfectly valid identifier that will prevent any further client developer or person touching the system to question if one should put v4 at the beginning or at the end of a URI (and I suggest that, from the server perspective, you shouldn't have 4 versions, but 4 media types).
I vote up for doing this in mime type but not in URL. But the reason is not the same as other guys.
I think the URL should be unique (excepting those redirects) for locating the unique resource. So, if you accept
/v2.0
in URLs, why it is not/ver2.0
or/v2/
or/v2.0.0
? Or even-alpha
and-beta
? (then it totally becomes the concept of semver)So, the version in mime type is more acceptable than the URL.
There are 4 different approaches to versioning the API:
Adding version to the URI path:
You can implement a controller in you code like this:
Request parameter versioning:
The implementation can be similar to this:
Passing a custom header:
With header:
or:
Possible implementation:
Changing Hostnames or using API Gateways:
If the REST services require authentication before use, you could easily associate the API key/token with an API version and do the routing internally. To use a new version of the API, a new API key could be required, linked to that version.
Unfortunately, this solution only works for auth-based APIs. However, it does keep versions out of the URIs.
You should NOT put the version in the URL, you should put the version in the Accept Header of the request - see my post on this thread:
Best practices for API versioning?
If you start sticking versions in the URL you end up with silly URLs like this: http://company.com/api/v3.0/customer/123/v2.0/orders/4321/
And there are a bunch of other problems that creep in as well - see my blog: http://thereisnorightway.blogspot.com/2011/02/versioning-and-types-in-resthttp-api.html