I think versioning API is an illusion.
It is all source of complexity that eventually kills us.
Give up keeping exactly the same behavior as actual models change.
I've always thought APIs should try to avoid versioning. It's usually pretty easy to enhance APIs in a backwards-compatible manner. It also forces smarter design and restraint. Existing users rarely update integrations until they are forced and then it is a major pain just to stay in place.
Suppose we replaced Semantic Versioning with any other approach (of your choice) that still disclosed the same amount of information about whether API was identical, had an additive change, or had a breaking change. Would you object to that model too ?
If so, it seems like you'd be effectively arguing that authors should simply not disclose important changes to the API. It is hard to imagine that position being defensible.
If not, why do you consider Semantic Versioning to be more hazardous?
I agree that there's a sound reason for this, but I can't help but think that API versioning would be the more correct way to do it. This is how you pile up unnecessary complexity.
Semantic Versioning is bullshit. Even "backward compatible features or bug-only fixes" can completely break your application.
With a sufficient number of users of an API,
it does not matter what you promise in the contract:
all observable behaviors of your system
will be depended on by somebody. -- Hyrum's Law
Versioning your APIs gives you a built-in metric for how often you make breaking changes. Not everyone likes seeing this, but if you can enforce it, I think it creates a psychological incentive to exercise discipline about API changes.
I have to disagree somewhat: versioning objects or endpoints is never the right solution. I'd go so far as to say that versioning the whole API is simply the least bad option.
What constitutes a major version? Simple: as soon as existing clients break it's a new major version. That means you can, for example, add new endpoints because that's not a breaking change. You simply can't remove or change any of the existing endpoints, fields or objects.
It also means that a client can't mix-and-match what major versions to use ie you can't use /v1/customer and /v2/account. Why? Because clients will do that as a quick hack and you need to save them from themselves.
So why not version endpoints or objects? Because of environment bifurcation. Let's say you have 2 API versions (v1 and v2). To verify your API you can test each independently. That's relatively easy.
But imagine you have 10 endpoints and each is versioned separately. Now you have to test 2^10 possibilities. Clients will do stupid things like use a different version as a quick hack or even when they don't need to and you'll be debugging those things forever. Don't give your API users footguns.
With just a bit of forethought and a little planning, an API almost never really needs to be versioned in either way. One of the problems with versioning is that it almost encourages changing the API and most consumers are slow to update, if at all.
Many developers said this to me (about API versioning) when I was a PM and somehow I struggled to believe it was as intractable as they said.
I suspect the reality is the human cost of dealing with versioning in an API is the problem. Not that "it can't be done" but that nobody wants to incur the downstream costs in their lived work, either of running a v1 and a v2 binding, or of managing transitions, or of the whole "is a superset capable of managing with the reduced subset" thing.
If you want to be light hearted, IPv4 -> IPv6 is a versioning example where clean break is demanded, and we're at 35% worldwide. Clearly, sometimes, you have to wear a 20+ year versioning cost.
I used to thought experiment "what if we wrote a complete functional client in python, for every version change we release, and gave it to every client" type ideas. Incur the cost in them, to convert for our benefit.
This is often good advice, but not in this case. Versioning your API is a trivial thing to do from the beginning and has massive consequences down the road. Some things are worth getting right in the beginning.
Versioning of APIs have existed since the dawn of time, or at least the early 90s. ONC RPCs had versioning built-in IIRC for all their XDR structs. We got away from that over the last few decades, and now people run into the same problems that were effectively solved almost 30 years ago, but long forgotten. The more things change, the more they stay the same!
Finally someone does versioning properly and enforce basic REST principles. URL versioning (v1,v2, etc) simply don't make any sense yet they are used all the time. API shouldn't ever change (on that version) once you release the version, yet we see new endpoints appear after v1/ all the time. You never know what's new what old feature in url versioning.
Imagine you release package on npm (or whatever) versioning it with v1 and constantly adding new features and still keeping the v1 version tag. That's what you're doing to your API.
If you don't version, you can only add to an API. You cannot change anything meaningful (or as simple as renaming a field). You wind up with APIs with multiple ways of getting the same or similar data in order to avoid breaking backwards compatibility, which leads to bloated, confusing APIs.
Semantic versioning doesn't make sense for user facing software. Maintaining API compatibility on the software -> user interface isn't really a problem/doesn't make sense compared to software -> software interfaces.
Although there are APIs used in production whose output changes/evolves over time.
First one that comes to mind is Google Translate. We spend 6-figures with the Google Translate API annually, and recently we went back and checked if Google Translate is improving/changing the translations over time, and found that they indeed are (presumably as they improve their internal models, which aren't versioned and isn't exposed in a changelog anywhere). The majority of translations were different for the same content today compared to 6 months ago.
I don't particularly agree with this approach. Speaking as a power user of Google Translate API, it would be nice to be able to pin to specific version/model and then manually upgrade versions (with a changelog to understand what's changing under the hood).
reply