APIv2 is not the same resource as APIv1, so why send it to the same location? Similarly, APIv1/user/1 may very well not contain the same information as APIv2/user/1, so are they really the same resource? They likely refer to the same semantic resource, but if user/1 != user/1, they're not the same from a data standpoint, which is what APIs are generally used for.
The correct method for selecting a specific representation is to use the Accept header on the request. For example, if I were requesting somedomain.com/Groxx I could specify Accept: image/png if I wanted a picture of you, or Accept: text/x-vcard if I wanted your contact information.
"The Accept request-header can be used to specify certain media types which are acceptable for the response."
Similar to how when you access some linked data URLs you can specify rdf/xml or rdf/n3 in the Accept header to receive the same data in a specific format.
It's not used to specify whether you want a picture of someone or their contact information all from the same URL.
You should also question whether you really need multiple representations for each resource -- in many cases, it's more trouble than it's worth to automatically generate, say, both JSON and XML responses, since it just divides your attention to creating sensible serializations for your API.
If you expect to have clients which cannot modify the headers of their requests, you can support fallbacks like specifying the Accept header in a query parameter. Putting it in the actual URL though is doing a disservice to fully compatible HTTP clients, though.
But if JSON is so inherent to the resource that content negotiation doesn't even matter, it can be fine to include that in the URL, as you might include descriptive filename extensions like ".png" or ".wav" in a URL.
Clearly it is a pragmatic trade-off and is popular (Google and Twitter do it). The correct answer will be arrived at by considering the total architecture of your application.
what 'API' is signaling is what the client is capable of understanding, which is what content negotiation headers are for
I think of it no different to the same resources for web browser consumption (for humans) - I don't place new designs of a website into /design1/ /design2/ etc.
That doesn't make REST "bad", but I think it does start to make the quasi-religious aspect of it less obviously correct.
It's a correctness vs usability debate. I'd love to go for correct, but it's extremely painful to enforce in your users in practice.
Anything else requires the client knowing how to mangle URIs (e.g. adding /avatar.jpg, /contact.vcf).
It has a dubious track record in X as well. X has been able to do content negotiation for decades for the clipboard but even now it's still spotty and buggy, and that's with everything actually running on the same system. It looks easy. Heck, it looks very easy. It isn't. I can't even tell you exactly why it isn't as easy as it looks (beyond the semantic thing I mentioned above), but the state of the world is pretty clear.
eg.?v=1&format=xml
but interesting to note is that why is encoding easy to do as part of content negotiation, yet everything else is hard? you never see ?e=UTF-8 or &c=gzip
The challenge is some HTTP library APIs commonly used for developing clients offer the following interface: - GET $URL
If you are lucky, then it might also support POST and offer a second parameter for the request body. If are really lucky, there is a way to specify arbitrary methods, but this is fairly rare.
I backed away from using content-negotiation for an API, part of which would have served data and part content.
e.g. to access file metadata, get /path/to/file with Accept: api/v1 and do a 'normal' GET to get the file contents.
I came across some suggestions that some browsers (recent IE I think, unsure) which suggested that cacheing was broken wrt Accept header - which made me worry that people hitting accessing the resource might get the wrong version.
I don't know if your api is vulnerable to this, if you've come across the problem or have any deployment wisdom to share.
It implies that a resource is different just because you are using a newer version of the API.
My own most recent implementations use Accept: and Content-Type to define version compatibility, which is what content negotiation is supposed to be about.
Versioning in the old web API sense meant changing the way the protocol works, and REST will always be REST and the resources will always be resources.
All that is likely to change between 'API versions' is formats, which you negotiate with headers, and adding new fields, which old clients can either ask not to get through content negotiation or can safely ignore.