37

I've evaluated a number of versioning schemas for REST apis (header, url, …). So far, the most reliable approach seems to be the url option: It works with proxies, and does not rely on obscure schemas such as dates for versioning.

Now, when I look around, everybody who uses the url based approach seems to use versions such as v1, v2, and so on. Nobody uses minor versions, or even a schema such as semantic versioning.

This raises some questions:

  • When do you increase the version number of a REST api (for sure, you have more updates to it than just once in five years)?
  • If you just have a bug fix, you probably do not increase the version number, but how do you differ both versions?
  • If you use a very fine-granular approach, you end up with lots of versions you need to host in parallel. How do you handle that?

In other words: How does a company such as GitHub, e.g., make to only have v3 today (2015), when they are around in business already for 7 years now? Does that mean that they actually only changed their api two times? I can hardly believe that.

Any hints?

Community
  • 1
  • 1
Golo Roden
  • 140,679
  • 96
  • 298
  • 425
  • 2
    Actually that's the major version number. I think resource versioning is much more important, but nobody talks about it. – inf3rno Jan 12 '15 at 13:32
  • Can you explain a little further what you mean by *resource versioning*? – Golo Roden Jan 12 '15 at 13:40
  • 1
    Ofc. when a resource changes, it has to change version number. By updating a client, it has to send the version number of the locally stored resource representation along with the request, and so the service will know whether it has a new version of the resource or not. People call this etag, but if you have a resource or response with multiple resources, you cannot send multiple etag headers (afaik), so you have to send the version numbers in the body. – inf3rno Jan 12 '15 at 13:50
  • Okay, that cleared it, thanks :-) – Golo Roden Jan 12 '15 at 14:05

1 Answers1

65

The major version number is all you need for a web service. Because your consumers are only concerned about backward incompatible changes, and (if you're following semantic versioning correctly) those will only be introduced when a new major version is released.

All other changes (including new features, bugfixes, patches etc.) should be 'safe' for your consumers. Those new features don't have to be used by your consumers, and you probably don't want to continue to run that unpatched version that contains bug X or Y any longer than necessary.

Using the complete version number in your URLs (or whatever method you use for API versioning) would actually mean that your consumers have to update the URL of your API everytime you make an update / bugfix to your API, and they would keep using an unpatched version until they do so.

This doesn't mean that you can't use semantic versioning internally, of course! Just use the first part (major version) as the version number for your API. It just doesn't make sense to include the full version number in your URL / header / other versioning system.

So to answer your question: you update your API everytime you make a new release, but you only release a new API version when you have a new major version. This way you only have to host a couple of different versions (and you can of course deprecate old versions over time).

Nic Wortel
  • 11,155
  • 6
  • 60
  • 79
  • Thanks for your great and very detailed answer! Just one thing left: Supposed the system is not hosted on the web, but installed at the customer, I do end up with lots of slightly different variants of a given major version, don't I? How do I handle this? In other words: I can't be sure that `v1` for one customer means the same as `v1` for another. – Golo Roden Jan 12 '15 at 12:42
  • Can you explain that scenario a little further? You are developing an API, that will be running on many customer's servers, but will only be available on their local network (and therefore only consumed internally)? Is that correct? – Nic Wortel Jan 12 '15 at 12:51
  • Correct. But we will have to support it. So, this means, a customer calls and complains about a problem with the REST api. We ask which version they use, and they tell us that it's `v1`. Unfortunately, this is not too helpful, as there may be many `v1`s out there. Of course we can ask for the specific server version, but that's an additional step (and we are unsure, whether we want to have it). Does this make the question clearer? – Golo Roden Jan 12 '15 at 12:54
  • 3
    Yes, I think so. Of course, the ideal solution would be to make sure that all servers are allways up-to-date with the latest version of the software. But that is probably out of your control. What about a route in the API that simply returns the full version number? Then you can direct people (who will mostly be developers, I assume) to that URL (such as `http://12.34.56.789/api/v1/version`) to find out the exact version. This would still require that extra step, though. There might be a better solution, but this is the best that I can come up with right now ;) – Nic Wortel Jan 12 '15 at 13:04
  • While I completely agree with this from a public perspective, I think that internally (or if you ship microservices to customers) there are significant advantages to using semantic versioning for APIs. If your organisation has a number of REST APIs that use each other then it can be very useful to have an API dependency between them. API-A 1.0.0 depends on API-B 5.0.0 to start with, but your feature development of API-A 1.1.0 needs a new non-breaking feature of API-B 5.1.0. It's not necessarily the same as the package versions. – dpwr Feb 07 '20 at 10:37
  • @dpwr You could expose your API both ways, internally or even externally, where the major (/v1/) points to the latest minor+patch and you could also expose explicit versions for customers that need that, it's just routing at that point. – robert arles Feb 10 '22 at 18:37