Common sense is disturbingly uncommon.
i’m going to be pretty clear here. If you’re going to version an API or service. Put the version in the URL, right after the host.
This is pretty much the only way to do it.
And here’s why:
First off, this is how you version your code. You use Major.Minor.Build
Major – introduces at least one non-backwards compatible function that will break clients. This is non-negotiable. There are no “small” changes that break functionality with clients. If you break your tests with a change, it’s a major version change. Period.
Minor – introduces one or more new features or functions but DOES NOT alter existing outputs. Older code written before the minor version will not know about the new feature, so it does not need to be reflected into the URL.
Build – Optional Fixes a bug to bring existing elements inline with published specifications.
The Code version is the contract you establish between yourself and your customers. It’s how you associate documentation and bugs with a given baseline.
The URL version value contains only the Major version. Why? Because if you’ve added a new feature (minor version update) code written prior to the minor update will have never called it. If you’ve altered what’s being returned or dropped a function, then it’s a Major version update.
Versions can be sunset. Ideally, with proper announcements and some out of channel means to alert developers that they need to use the new version. An old version should be maintained for a minimum of six months, but realize that commercial applications (like TVs) may have VERY long update cycles, and you may need to keep an API version live for 5 years. Maintaining older versions of APIs is still up to the kindness and discretion of the service provider.
So, some Q&A:
- Why put the version in the URL with a “v” prefix?
- Using “v” indicates an explicit version tag, with the number being the Major version. It’s a clear specification and agreement between you and your customer. It’s a virtual handshake that both sides agree to.
- What about putting the version in the headers?
- Ok, so what version does a user get if they don’t specify the header? What if their client can’t provide the header or it’s stripped by a firewall/proxy? Do they get the latest major version with all of the client breaking changes? Are you really not that fond of having skin or a non-smoldering workplace?
- What about putting the version in the body of the request?
- This is why your developers and QA hate you. In order for this to work, your code will need to continue to maintain older, often highly conflicting calling structures. This, or each server must proxy calls to older systems which can greatly complicate things. This means more tests, longer QA cycles, and developers who are far beyond the Balmer Peak. Putting the version in the URL allows calls to be routed to different applications.
- What about putting the version in the hostname/port/other location?
- This is why your ops folk hate you. In order to do this, they need to modify DNS servers every time a new version is made available, wait for propagation, trust clients will discover the endpoint and possibly get new SSL certs. Do not make your ops folk hate you. They specialize in making your life a living hell.
- i’ve got a fix that changes the returned data from a list to a hash or changes the name of a returned item, that’s a minor thing, right?
- No, it’s not. Unless all possible reading code can deal with the alteration with zero modification or change in behavior, it’s a Major change.
- Doesn’t that mean we’d constantly be pushing out major versions?
- Yes. That’s why you think long and hard about your Major versions, returned results, and actions, rather than push out whatever sounded good after a half hour discussion over a few beers. You will make mistakes. You will need to change things. Every time you do, though, you run the risk of breaking client code and losing anyone who was using your older API. Making APIs is not easy and requires you to think not only as a provider, but a consumer. APIs limit how fast you can “turn on a dime” and “rapidly iterate”. It may well be that having a public API (or building a company off of one that’s just been released) may not be a good idea. This is why it’s important to listen to your customers and report your bugs to your providers.
There, hopefully that’ll prevent you from having folks like me pop out of a bush with a baseball bat on your way out of the office tonight.