Need someone to lead product management at your software company? I build high-craft software and the teams that build it. I'm looking for my next opportunity. Check out my resume and get in touch.

This is the blog of Adam Kalsey. Unusual depth and complexity. Rich, full body with a hint of nutty earthiness.

Versioning web services

Freshness Warning
This blog post is over 18 years old. It's possible that the information you read below isn't current and the links no longer work.

When I add a new feature to Tagyu’s web service API, how should I best version it? I don’t want to maintain and support multiple, old copies of the API, but I also need to ensure I don’t break backward compatibility. A change to the API can’t cause existing apps out there to stop working.

At first I thought this was an easy problem. I’d simply ensure that any time I made a change to the API the changes would be additive. I wouldn’t remove any data, I wouldn’t change the location of representation of the data, I’d only add new data. If a case came up where I needed to change how the XML data is stored, then I’d consider maintaining parallel versions of the API for a period of time. I’d figure out how to do that when the time came. Amazon Web Services inserts their API version into the URL, but that’s always seemed a bit clunky to me.

Today’s new API feature made me rethink how I change the API and represent different versions. It made me rethink what changes should be even considered as a new version. Today’s change involved the insertion of a couple of attributes to one of the XML tags. Shouldn’t be a problem right? That’s what I thought, too.

Before the change, the XML node for a suggested tag looked like this:

<tag>sometag</tag>

After the change, it looked like this:

<tag rel="related" href="http://tagyu.com/api/tag/sometag">
	sometag
</tag>

Those two new attributes broke some APi implementations, including my own software, the Tagyu Movable Type plugin. The plugin uses XML::Simple to parse the API’s response. And as far as XML::Simple is concerned, those two formats are completely different XML structures. XML simple represents the first one as this…

{
    'tag' => 'sometag'
}

And the second as this …

{
	'tag' => {
	 	'rel' => 'related',
		'href' => 'http://tagyu.com/api/tag/sometag'
		'content' => 'sometag'
	 }
}

The Tagyu plugin accesses the tag through $tags->{'tag'} but under the new structure, that’s not the tag at all, it’s a hash that contains the tag, among other things.

The point of all this is that even though I thought I was being careful, today’s API change broke things. And that’s bad. It should never happen.

I’m looking for thoughts on how to version a web services API or really any software that’s delivered as a service. How do you prevent changes from having adverse effects while at the same time providing improvements. Is different API versions at different URLs really best or only way to go?

Recently Written

Building the Next Big Thing: A Framework for Your Second Product
Nov 19: You need a first product sooner than you think. Here's a framework for helping you identify a winner.
A Framework for Scaling product teams
Oct 9: The people, processes, and systems that make up a product organization change radically as you go through the stages of a company. This framework will guide that scaling.
My Networked Webcam Setup
Sep 25: A writeup of my network-powered conference call camera setup.
Roadmap Outcomes, not Features
Sep 4: Drive success by roadmapping the outcomes you'll create instead of the features you'll deliver.
Different roadmaps for different folks
Sep 2: The key to effective roadmapping? Different views for different needs.
Micromanaging and competence
Jul 2: Providing feedback or instruction can be seen as micromanagement unless you provide context.
My productivity operating system
Jun 24: A framework for super-charging productivity on the things that matter.
Great product managers own the outcomes
May 14: Being a product manager means never having to say, "that's not my job."

Older...

What I'm Reading