Why SemVer doesn't make sense for web APIs
At the office, there is a push to using tools like Cocogitto more so that we can automatically generate the next (correct) semantic version of web services. I would like to share my thoughts on why I don’t think that this makes a lot of sense.
With Semantic Versioning, a software package author can communicate to their users how “safe” an upgrade from one version to another is. From the SemVer website: “Under this scheme, version numbers and the way they change convey meaning about the underlying code and what has been modified from one version to the next.”
- Patch version increases (A.A.A -> A.A.Z) should not touch the API of the package. You should be able to upgrade safely. Examples: bug fixes or performance improvements.
- Minor version increases (A.A.A -> A.Z.A) change the API of the package, but in a backwards-compatible way. It should also be safe to upgrade between those two versions, but the changes are typically bigger and slightly riskier than patch releases. Example: adding a new function or adding a new optional argument to a function.
- Major version increases (A.A.A -> Z.A.A) change your package’s API in a non-backwards-compatible way. Doing this upgrade will likely require you to rework some part of your own software as result of the upgrade. Example: code deprecations, adding non-optional arguments to functions
For software libraries, this makes total sense. For web apps, I argue it doesn’t:
- Patch version increases should be transparent to the user. If a bug is fixed, the users of the service should automatically be calling the now bug-free version of your service. Otherwise, all clients of your service would have to update a version number, just to use your new version. This way, you lose a benefit of having a runtime dependency. It would also require that your clients keep much closer track of your versions/deployments.
- Minor version increases follow the same logic. The change should be backwards-compatible, so why not include it immediately in the currently available API? You can communicate that the new functionality is available and let your clients consume it whenever they’re ready for it. The alternative would be to provide a new, parallel version of your API that clients need to migrate to in order to get to the new functionality.
- Major version increases is where versions become necessary. When making a breaking change, you will need to run your old and new API in parallel for a while, to give clients the chance to upgrade. This is where a version number comes into play. When the old API is no longer in use, you can decommission it.
This is the reason why most services/APIs you see “in the wild” have a version number like /api/v1 or /api/v2/ in their paths, but not /api/v1.13.4. It’s always just a major version, because consumers of the API only care about breaking changes. Any non-breaking changes are expected to be added to the service without any work on the client’s part.
But PJ, what about using SemVer as an internal version for the devs? Well, you can set that up, but why would you? There are many version schemes you can use. The easiest one is probably just to use the pipeline number as the version for your software. It auto-increments and should be easily available from the pipelines you use to build and deploy. No extra tooling required. SemVer is about communicating to your service’s clients. You most likely don’t need this kind of communication within your team. At least not through version numbers.
So what about the CHANGELOG that Cocogitto generates? Ok, you got me there. If you want a changelog, using Cocogitto and Conventional Commits can make sense. But ask yourself if you really need this changelog. This file is also used to communicate changes to end users, but in more detail than the version number. Do you really need this kind of communication for a web service? Do you have a lot of anonymous users that are interested in following every last change to your service? Or do your users mostly track the changes they’re interested in through your ticketing system?
If you don’t really need it, just spare yourself the setup and maintenance cost of incorporating an extra tool in your setup. KISS