7

I'm designing an API for our web application, that will be consumed by mobile developers that will create our mobile app.

I chose to document it using Swagger / OpenAPI 3.0.0.

I'm surprised that when I create a new OpenAPI document on Swagger, I get a default version field set to 1.0.0.

The specification also uses 1.0.1 as an example.

While I understand very well, and implement myself, semantic versioning for open-source libraries, I fail to understand how this relates to APIs. An API is, by definition, always up-to-date, and I my gut feeling agrees with this answer on StackOverflow. Full quote:

APIs should only use major versions externally. Following best practice semantic versioning, major versions change when you introduce backwards-incompatible changes to a project.

If you're just adding features, or modifying existing ones in backwards-compatible ways, then you just do it and your existing consumers are not affected (though, they can then make use of the new changes if they want). Your API can change versions from 1.0.0 to 1.1.0 internally, but the version as exposed to your consumers is still just "v1".

If you're just patching bugs, the same applies. Change from 1.0.1 to 1.0.2 internally, but the API should stay at "v1".

Now, if you rename/remove resources, or do some other drastic changes that will break existing clients, your internal version might go from 1.2.0 to 2.0.0, because breaking backwards compatibility requires a major version change. Because of this, the new major version has to be exposed to your API's consumers as "v2".

So, in keeping with this, both your namespaces and your URLs should reflect only the major version (e.g. "v1"), and you should make sure that you never break backwards-compatibility within a major version.

Should I version my API using only a major version, or major.minor.patch as I would with an open-source library?

What's the point in introducing bug fixes and new features as new versions, when you can apply them to the existing version directly?

My main worry is that if I follow this convention, if I fix a bug on v1.0.0, and release the fix as v1.0.1, I would have to let developers know so that they could update to the next patch version, and then wait for end users to update their app.

Whereas if I apply the fix to a v1 API directly, the fix will instantly propagate.

What did I miss?

BenMorel
  • 315

1 Answers1

9

Should I version my API using only a major version, or major.minor.patch as I would with an open-source library?

You should use major.minor.patch (or major.minor.patch.build)

Your quoted article is correct in that because the internal implementation is not exposed to the client, they wont care about anything other than the major version. Only a change which breaks the interface will affect them and by definition this would be a major change*

Your routing of requests should reflect this, you don't want to force clients to request a specific patch version.

However! for your own sanity you will care very much about the exact major.minor.patch.build version which is deployed to your many servers. You will want this version to be logged and reflected in the assembly versions which are deployed. So that you can do basic debugging and versioned deployments etc.

*You can imagine edge cases where the internal processing affects the result without breaking the interface. You can also imagine some clients not wanting the 'fixed' version for whatever reason.

What I normally do is allow the full version to be requested but route according to my own wishes. for example I might route:

v0.*.*.* -> unsupported error page  // all v0s go to an error page that tells the client to upgrade
v1.*.*.* -> v1.2.0.0   // all v1s go to the latest v1
v1.1.32.1 -> v1.1.32.1  //need for client who is audited on changes
*.*.*.* -> v2.2.0.0 // all not matched by other rules or unspecified go to my latest version
Ewan
  • 83,178