DEV Community

RESTful API Versioning Best Practices: Why v1 is #1

Chris McFadden on September 19, 2017

Breaking Changes Bad! API Versioning Good! As anyone who has built or regularly uses an API realizes sooner or later, breaking change...
Collapse
 
yellowbrickcode profile image
Sarah Williams

Really interesting read, thanks for posting. This is something creeping up my to-do list for me to start defining as I get closer to the point of me needing to declare something as version 1 of my API so came at a good time for me!

Collapse
 
asbjornu profile image
Asbjørn Ulsberg

I wish I could agree, but I don't. With API versioning, you're only postponing or ignoring the problems you're going to have to face down the line anyway. As with most problems that are eventually going to hit you like a bus, you should tackle them as early as possible before the bus gains momentum and finally kills you. Ok, an API with a version number likely won't kill you, but please bear with me. :-)

When you have 4 different versions of your API available, each with something like 20 individual resources, that's 80 different resources you need to support. If you share codebase between all of these different versions, how can you guarantee that a feature added in version 4 won't break something in version 1? If you split the codebase between the 4 versions, you have four times as much work on your hands in terms of maintenance, bug fixing, etc. If each version is independently deployed, documented, etc., that's also a lot of overhead and duplicated effort. Can your company really sustain that in the long run? Is it worth it?

Versioning your API doesn't deal with having a plan for how to deprecate, rename and remove things either. Adding a new version of your API does not automatically remove old ones. They are there because you need to support the features they provide, at the precise URLs they all live, forever and ever. Also, versioning the resources in your API is way more coarse grained than necessary. If you have 20 resources and remove one property in one of them, why should the 19 untouched resources also have their version number incremented?

Instead of a version strategy, you should have a change strategy. That means you should plan how to introduce new features and how to introduce breaking changes. You should figure out the answers to questions like: Who needs to be notified when something changes? How are you going to notify them? If your plan to deprecate something turns out difficult to a customer, can you postpone the removal of that feature?

These are questions you will have to answer even if you have version numbers in your APIs, it's only that you will get them at a much later stage when it's much harder to deal with. Deal with them upfront and it's going to be much easier, because you can design everything around being able to simply answer these questions.

If you want to remove a feature (say a property from a resource), you can for instance start by removing it from the API documentation and notify existing customers of its deprecation via e-mail or on a dashboard they view often. Then you can monitor the usage of said feature and notify customers who still use it. If they still don't update their clients, you can offer them money to do it. That's money you're going to save by not maintaining the old version, so it's a win for both parties.

As outlined by Zdenek Nemec in API Change Management, the rules for extending your API is simply:

  1. You MUST NOT take anything away
  2. You MUST NOT change processing rules
  3. You MUST NOT make optional things required
  4. Anything you add MUST be optional

And you should version things, just not the resources themselves. Here's what you should version:

  • Server has a version
  • Client has a version
  • Message format passed between server and client has a version (but should rarely change)
  • API description file has a version
  • Resource doesn’t have a version
  • Relation between resources doesn’t have a version
  • API itself doesn’t have a version

So, how does this work in practice, then? Through content negotiation, and most importantly; hypermedia. If this has you intrigued, please spend 20 minutes watching my presentation on hypermedia to get an idea of what it is and how you can use it to create more flexible APIs without the need of version numbers.

Collapse
 
cristoirmac profile image
Chris McFadden

In general I agree with you. Perhaps my point was lost. Versionless API is what I recommend, with a strategy for managing change. You might find my QCon talk on this subject interesting - there is a recording. sparkpost.com/blog/microservices-b...

Collapse
 
rafalpienkowski profile image
Rafal Pienkowski

Nice comment to this article. Sticking to version 1, as the final version of our API, it the most convenient approach. In my opinion it extremely hard to achieve this in real life scenarios and we should keep in mind that in the future we'll be pushed to release new version of our API to meet customers requirements.

Collapse
 
rafalpienkowski profile image
Rafal Pienkowski

Nice article which show new point of view on API versioning. Unfortunately in my career I've had always to introduce new version of API to introduce new features for my clients and I end with multiple versions of API which should be maintained.

Collapse
 
cristoirmac profile image
Chris McFadden

Thanks for reading, Rafal. "Versionless" APIs are definitely becoming more popular, for good reason. Hopefully, you will get a chance to adopt this approach in the future. You may find my QConSF talk on the subject interesting. sparkpost.com/blog/microservices-b...

Collapse
 
rafalpienkowski profile image
Rafal Pienkowski

In green field projects I'm going to use "versionless" API but I need to maintain existing one which weren't designed to achieve this.
I'm sure that I'll look at it. Thanks for your replay.

Collapse
 
Sloan, the sloth mascot
Comment deleted
Collapse
 
lirantal profile image
Liran Tal

for Node.js / ExpressJS readers - github.com/lirantal/express-versio...
would be happy to get feedback :)