After reading a few comments on reddit and by email about my post on versioning of REST APIs I see that I wasn't clear on terminology and have left out some context. That's okay! Overthinking details is the main killer of all my interesting thoughts :-) I'd rather post more and repeat myself on occasion.
What's "backwards incompatible", exactly?
The main point of contention was that there's no problem, really: if an API changes incompatibly, existing clients could just use the old version of an API. Hence, a version bump in the URL is seen as a solution, letting many versions to co-exist in the public space. There was even a suggestion to keep all versions indefinitely.
Well, consider these situations, off the top of my head:
You want to remove a feature from an API for business reasons. Keeping an old version simply defeats the purpose.
Someone found a security hole in an old version. Even if there's no bug anymore in the current version, you will have to dig through all the active old ones and patch them. The more of them, and the older they are, the more costly it becomes. Sometimes a fix would make a version backwards incompatible which, again, defeats the purpose of keeping it.
With growing load, your API needs a performance overhaul by, say, replacing granular update operations with a bulk one. Even if you could technically keep the old version active, you don't want that, because the point is to get rid of the performance bottleneck.
I'm going to go ahead and even postulate this:
if you are able to keep an old version of the API working alongside a new one, you shouldn't make the change backwards incompatible at all.
Why invalidate clients
So, when old functionality eventually dies, even after you supported it for some time, the clients that use it are invalidated. It is not a question of "if".
The question is, then, "how":
- You either explicitly change the version number in the root of your URLs, or
- you change versions and/or representations of only those resources that has suffered the change.
The crux of my argument in the previous post was that the latter is better because it avoids invalidating clients that don't use the broken resource.
A simple to imagine example would be a read/write API, like Twitter's. If you change the writing, your clients that only read don't even need to know about it. Which may be a majority of them. Or change in the authentication protocol that doesn't affect anonymous clients.
This bit caused some confusion, too:
It constrains development on the server as you have to synchronize releases of independent backwards incompatible features to fit them into one version change.
Here, I shouldn't have used the word "have". What I meant is that since you want to minimize the amount of breaking changes, you might want to shove many little breaking changes that's been cooking up in your code base into one public update. This requires synchronizing.
But I admit that, while completely real, it's rather a weak point.