Howard Dierking

An API by Any Other Version

“A rose by any other name would smell as sweet”

I’ve written and spoken on the topic of API versioning numerous times over the last several years - particularly in regard to RESTful APIs. However, as APIs become more mainstream and the number of scenarios and expectations grows, it seems like it may be time for another turn of the crank in thinking about API versions. As always, these are just my thoughts, and I’m always interested in hearing yours.

In previous posts, I’ve addressed API versioning from an almost purely technical (or architectural) perspective. In considering recent discussions, I think this narrow focus may be problematic. In this post, I would like to step back and ask a more basic question: who is the audience for an API version and what is his/her expectations of that version?

As I’ve had the opportunity to observe the “API Economy” evolve over the last several years, I’ve noticed that the audience for APIs has extended beyond the traditional developer crowd. For example:

And of course, let’s not forget about the developer, who ultimately needs to write code tht binds and makes calls to your service. Given these different stakeholders and their respective concerns, an API version number needs to communicate a variety of different assertions about an API.

telsa facing left telsa facing left

(Both pictures here are of a Tesla Model S. However, there could be about 100,000 USD difference between them, so that model number is pretty important.)

Hopefully at this point, you’ll agree that a version number can mean different things to different people and it’s not simply about denoting changes to code. The next point of discussion that often follows is around where the version number should go - or, put a different way, what should be versioned?

I’ll open up this part of the discussion by committing a logical fallacy (albeit a good one). A few years ago when I started immersing myself in the REST world, I remember having a discussion with Henrik Nielsen where I was trying to impress him with my newfound knowledge of resources, representations, and their respective metadata. Much of my thinking at the time was reflected in my first versioning post. Henrik, being the ever-patient, good guy that he is, simply smiled and said something to the effect of “they’re all resources - just give them URLs.”

I was confused. How could somebody who worked with folks like TBL and Fielding not agree with my brilliant, nuanced understanding of REST?? At any rate, I published my thinking and continued building and researching. As I started getting deeper into researching, however, this view started making more sense to me for the following reasons.

Pulling this back to the discussion of API versioning, I would like to ask you to consider the following:

API versioning is not about versioning at all - it’s about unambiguous names

In the world of Web APIs (and certainly in the world of linked data), names are fully-qualified URIs. The namespace property of URIs inherently makes them unambiguous. Splitting a name between a URI and some blob of metadata is a great way to introduce ambiguity. So, echoing the comments I made in the past, different representations are still resources, and name resources using a fully-qualified URI.

Now, the great things about a single, consistent way of naming things combined with the level of indirection provided by a resource is that you can have multiple names for the same thing at a point in time. The best illustration of this idea for developers is, in my opinion, Git.

Git logo

At its core, Git is simply a collection of immutable commits. Every committed change gets its very own name/identifier in the form of a SHA1 hash. However, because working with Git would be arguably more difficult if a requirent included memorizing and entering hash codes, Git supports higher level constructs such as tags and branches, which are little more than friendly labels that point to a specific commit. So an operation like git merge my-awesome-topic-branch is really just a friendly way of saying git merge 086ad264cce0b50bbb8f4c5475cefec52ab696f6.

In the Web API world, there are lots of great tools and techniques that we have available for providing this same kind of Git-like friendliness, even in a world of lots of URIs. The most often used technique is content-negotiation - either server-driven or client-driven. While this post is already getting long, I’ll avoid going into the details of content-negotiation strategies and instead provide you a reference implementation. However, I’ll mention here that techniques such as what I’ve described here goes beyond versioning and includes all types of variations, including different representations.

So I guess you could say that this post now constitutes “v3” of my thoughts on versioning Web APIs. I hope that it gave you a new and possibly different way of thinking about versioning. At the very least, I hope that the Shakespearian reference was mildly entertaining.