How do you version public web APIs?
20 points by jussi
20 points by jussi
Often there is an existing API called something like "Product API". It often also has /api/v1 in the path.
To me this often feels like an antipattern, especially when the API itself uses semantic versioning: mixing the routes with the API contract.
Having /v1/ in the URL while also having a major.minor.patch version: coupling the first number of the semantic version to the URL path feels counter intuitive to me, if you make a breaking change, you may need new paths and new reverse proxy routes, and whatnot, and you also spread the API contract to two places, the URL and the version number.
If you start simultaneously building a brand new successor to the "Product API", the old API is effectively stuck as "v1", even if it gets breaking changes of its own.
What do you think?
Do you have any API design pet peeves or opinions to share?
Sorry for the confusing brain dump text, very interested in hearing people's opinions.
Thank you
Having /v1/ in the URL while also having a major.minor.patch version: coupling the first number of the semantic version to the URL path feels counter intuitive to me, if you make a breaking change, you may need new paths and new reverse proxy routes
This is in fact one of the major benefits of doing a /v1/, because it forces you to not break the API for users until you disable the endpoint.
Fundamentally I just do /v1/, /v2/, etc, on each individual route, to signify breaking changes. For a live public API that isn't trying to define some standard that works on multiple hosts, there's no sense in doing full semver, because it really exists just to enable other developers to confidently upgrade dependencies without having to spend 20 minutes reading changelogs. On a live API people don't get to decide when to pull in new minor versions or bugfixes.
As for what constitutes a breaking change, I consider it a breaking change if it changes documented behavior, or breaks an existing client relying on documented behavior. Some places consider changing undocumented behavior to also be breaking changes, but there be dragons.
This is how folks at Google do it:
Though I find these design docs to be very specific to the way Google works, I've been consulting it when designing APIs, and some of the ideas found in it have been very useful :)
In general I think all APIs should strive towards limiting breaking changes to the absolute minimum. As an example, if you want to rename an attribute I'd say duplicate it instead.
That said, I also think the way the people at Buttondown do it is neat: Define migrations between API versions so that consumers can pin their API version with a header whilst still letting you as the provider make changes.
Expecting API providers to provide migrations between API versions as you describe seems like a good idea, but using an HTTP request header for versioning can cause problems.