<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Peter Williams &#187; rest-versioning</title>
	<atom:link href="http://barelyenough.org/blog/tag/rest-versioning/feed/" rel="self" type="application/rss+xml" />
	<link>http://barelyenough.org</link>
	<description>… and there is much to be learned</description>
	<lastBuildDate>Mon, 21 May 2012 14:29:17 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<item>
		<title>Bookmarks and URI based versioning</title>
		<link>http://barelyenough.org/blog/2012/05/bookmarks-and-uri-based-versioning/</link>
		<comments>http://barelyenough.org/blog/2012/05/bookmarks-and-uri-based-versioning/#comments</comments>
		<pubDate>Tue, 15 May 2012 14:44:53 +0000</pubDate>
		<dc:creator>Peter Williams</dc:creator>
				<category><![CDATA[Software Development]]></category>
		<category><![CDATA[hypermedia]]></category>
		<category><![CDATA[REST]]></category>
		<category><![CDATA[rest-versioning]]></category>

		<guid isPermaLink="false">http://barelyenough.org/?p=659</guid>
		<description><![CDATA[Threads about how to version hypermedia (or REST) APIs are multitude. I certainly have made my opinion known in the past. That being said, the most common approach being used in the wild is putting a version number in the URI of the resources which are part of the API. For example, http://api.example.com/v1/products/42. That approach [...]]]></description>
			<content:encoded><![CDATA[<p>Threads about how to version hypermedia (or REST) APIs are multitude. I certainly have made <a href='http://barelyenough.org/blog/tag/rest-versioning/'>my opinion known in the past</a>. That being said, the most common approach being used in the wild is putting a version number in the URI of the resources which are part of the API. For example, <code>http://api.example.com/v1/products/42</code>.</p>
<p>That approach has the advantage of being simple and easy to understand. Its main downside is that it makes it difficult for existing clients to switch to a newer version of the if one becomes available. The difficultly arises because most existing clients will have bookmarked certain resources that are needed to accomplish their goals. Such bookmarks complicate the upgrade quite significantly. Clients who want to use an upgraded API must choose to rewrite those bookmarks based on some out of band knowledge, support both the old and new version of the API, or force the user to start over from scratch.</p>
<p>None of these are good options. The simplest, most attractive approach is the first. However, forcing clients to mangle saved URIs reduces the freedom of the server to evolve. The translation between the two versions of the API will have to be obvious and simple. That means you are going to have to preserve key parts of the URI into the new structure. You cannot switch from a numeric surrogate key to a slug to improve your SEO. Likewise, cannot move from a slug to a numeric surrogate key to prevent name collisions. You never know when the upgrade script will be executed. It could be years from now so you will also need to maintain those URIs forever. Some clients have probably bookmarked some resources that you do not think of as entry points, you will need to be this careful for every resource in your system.</p>
<p>The second option, forcing clients to support both versions of the API, is even worse that the first. This means that once a particular instance of a client has used the API it is permanently locked into that version of that API. This is horrible because it means that early users cannot take advantage of new functionality in the API. It is also means that deprecated versions of the API must be maintained much longer than would otherwise be necessary.</p>
<p>The third option, forcing users to start over from scratch, is what client writers must do if they want to use functionality which is not available in the obsolete version when there is no clear upgrade path between API versions. This is not much work for the client or server implementers but it seriously sucks for the users. Any configuration, and maybe even previous work, is lost and they are forced to recreate it.</p>
<h2 id='a_way_forward'>A way forward</h2>
<p>Given that this style of versioning is the most common we need a solution. The <a href='http://tools.ietf.org/html/rfc5988'>link header</a> provides one possible solution. We can introduce a link to relate the old and new versions of logically equivalent resources. When introducing a breaking API change the server bumps the API version and changes the URIs in any way it likes, eg the new URI might be <code>http://example.com/v2/products/super-widget</code>. In the old version of the API a link header is added to responses to indicated the equivalent resource in the new API, eg <code>http://example.com/v2/rels/v2-equivalent</code>.</p>
<pre><code>&gt;&gt;&gt;
GET /v1/orders/42 HTTP/1.1
...

&lt;&lt;&lt;
HTTP/1.1 200 OK
link: &lt;http://example.com/v2/orders/super-widget&gt;; rel=&quot;alternate http://example.com/v2/rels/v2-equivalent&quot;
...</code></pre>
<p>Older clients will happily ignore this addition and continue to work correctly. Newer clients will check every response involving a stored URI for the presences of such a link and will treat it as a redirect. That is, they will follow the link and use the most modern variant they support.</p>
<p>If you are really bad at API design you can stack these links. For example, the v1 variants might have links to both the v2 and v3 variants. Chaining might also work but it would require clients to, at least, be aware that any intermediate version upgrade link relations so that they could follow that chain to the version they prefer.</p>
<p>You could also add links to the obsolescent variant&#8217;s body. This would be almost equivalent except that it requires clients to be able to parse older responses enough to search for the presence of such a link. Using the HTTP link header field nicely removes that requirement by moving the link from the arbitrarily formatted body to the HTTP header which will be supported by all reasonable HTTP clients.</p>
<p>Using URIs to version APIs may not be the cleanest way to implement versioning but the power of hypermedia allows us to work around its most obvious deficiencies. This is good given the prevalence of that approach to versioning.</p>
]]></content:encoded>
			<wfw:commentRss>http://barelyenough.org/blog/2012/05/bookmarks-and-uri-based-versioning/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>REST/HTTP Service Versioning (Response to Jean-Jacques Dubray)</title>
		<link>http://barelyenough.org/blog/2008/05/resthttp-service-versioning-reponse-to-jean-jacques-dubray/</link>
		<comments>http://barelyenough.org/blog/2008/05/resthttp-service-versioning-reponse-to-jean-jacques-dubray/#comments</comments>
		<pubDate>Mon, 19 May 2008 05:54:39 +0000</pubDate>
		<dc:creator>Peter Williams</dc:creator>
				<category><![CDATA[Software Development]]></category>
		<category><![CDATA[REST]]></category>
		<category><![CDATA[rest-versioning]]></category>

		<guid isPermaLink="false">http://pezra.barelyenough.org/blog/?p=341</guid>
		<description><![CDATA[Jean-Jacques Dubray takes issue with my approach of using content negotiation to manage service versioning in HTTP. I actually hesitate to respond to Mr. Dubray because the overall tone of his piece is rather off putting. On the other hand, he raises a couple of interesting questions which I have been really looking for and [...]]]></description>
			<content:encoded><![CDATA[<p><a href='http://www.ebpml.org/blog/89.htm'>Jean-Jacques Dubray takes issue</a> with <a href='http://pezra.barelyenough.org/blog/2008/05/versioning-rest-web-services/'>my approach of using content negotiation to manage service versioning</a> in HTTP. I actually hesitate to respond to Mr. Dubray because the overall tone of his piece is rather off putting. On the other hand, he raises a couple of interesting questions which I have been really looking for and excuse to talk about. So I will give it a go.</p>
<h3 id='handling_obsolescent_service_providers'>Handling obsolescent service providers</h3>
<p>Mr. Dubray asks how we deal with version skew between the client and server.</p>
<blockquote>
<p>Backwards compatibility is when the consumer comes in with a &#8220;newer&#8221; request version than the service provider can provide. This is common when a consumer uses different providers for the same type of service. So ultimately, you need to provide some room to define the version of both the consumer and the version of the service provider that it is targeting. Your mechanism only supports &#8220;one version&#8221;.</p>
</blockquote>
<p>Not true, the versioning mechanism I describe easily handles multiple versions. First, lets be clear, a service provider cannot provide capabilities that where not conceived of until after it was written. So Mr. Dubray must be interested in is the ability of a single consumer to successfully communicate with multiple versions of the service provider. I agree with him that this is an absolutely vital feature of any versioning mechanism.</p>
<p>Fortunately, content negotiation deals with this issue quite handily. I left this out of the original post for simplicities sake but it well worth talking about. HTTP allows user agents &#8211; or service consumers, if you prefer &#8211; to specify more than one acceptable response format. For example, the following is a perfectly legal HTTP conversation.</p>
<pre><code>===&gt;
GET /accounts/42
Accept: application/vnd.myapp-v2+xml, application/vnd.myapp-v1+xml;q=0.8

&lt;===
200 OK
Content-Type: application/vnd.myapp-v1+xml

&lt;account&gt;
  &lt;name&gt;Inigo Montoya&lt;/name&gt;
&lt;/account&gt;</code></pre>
<p>The <a href='http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html'>Accept header field</a> in the request indicates that the consumer can operate using either version 1 or 2 of the API but it prefers version 2. Accept headers can include any number of MIME media types along with preference indicators (the q=number part). This allows consumers to inform the server of all acceptable dialects of the API with which it can work. In the example, the server obviously did not support version 2 of the API and therefore responded using version 1.</p>
<h3 id='resource_deprecation'>Resource deprecation</h3>
<p>Further along Mr. Dubray asks this question,</p>
<blockquote>
<p>Another flaw of your versioning strategy is that URIs are by default part of the versioning strategy. I have often pointed out that &#8220;Query-by-examples&#8221; are encoded by members of the REST community (MORCs) in a URI syntax, for instance:</p>
</blockquote>
<blockquote>
<pre><code>/customer/{id}/PurchaseOrders ...</code></pre>
</blockquote>
<blockquote>
<p>Peter, how do you express that a particular QBE belongs to one version and not to the other?</p>
</blockquote>
<p>I don&#8217;t. The set of purchase orders associated with a particular customer is not version specific. The customer has agreed to purchase the same things regardless of which version of the service you are talking to.</p>
<p>Perhaps the question Mr. Dubray is really trying to ask is, what happens if you want to deprecate such resource?</p>
<p>(One reason to do so might be that the purchase order collections become too big to reasonably render in a single response. There are other, better ways to solve that particular problem but it is a nice concrete use case for resource deprecation.)</p>
<p>Resource deprecations is easily handled in REST using media types to handle versioning. First some ground rules, user agents should <em>never</em> be constructing such a URI. Doing so should be a gross violation of the HATEOAS constraint of REST. Rather they would be extracting that URI from the representation of the customer provided by the server. In such a case, an HTTP conversation getting the purchase orders for a customer might look like this.</p>
<pre><code>===&gt;
GET /customer/42
Accept: application/vnd.myapp-v1+xml
&lt;===
200 OK
Content-Type: application/vnd.myapp-v1+xml

&lt;customer&gt;
  &lt;purchase-orders href=&quot;http://service.example/customer/42/purchase-orders&quot;/&gt;
&lt;/customer&gt;

===&gt;
GET /customer/42/purchase-orders
Accept: application/vnd.myapp-v1+xml
&lt;===
200 OK
Content-Type: application/vnd.myapp-v1+xml

&lt;purchase-orders&gt;
  ...
&lt;/purchase-orders&gt;</code></pre>
<p>At version 2 of the API we deprecate the all-purchase-orders-for-customer resource &#8211; removing all references to it in the customer representations &#8211; and replace it with a purchases-order-by-month-by-customer resource. A similar HTTP conversation with a client capable of handling version 2 of the API would look like this.</p>
<pre><code>===&gt;
GET /customer/42
Accept: application/vnd.myapp-v2+xml
&lt;===
200 OK
Content-Type: application/vnd.myapp-v2+xml

&lt;customer&gt;
  &lt;purchase-orders-by-month href-template=&quot;http://service.example/customer/42/purchase-orders?in_month={xmlschema-gYearMonth}&quot;/&gt;
&lt;/customer&gt;

===&gt;
GET /customer/42/purchase-orders?in_month=2008-05
Accept: application/vnd.myapp-v2+xml
&lt;===
200 OK
Content-Type: application/vnd.myapp-v2+xml

&lt;purchase-orders&gt;
  ...
&lt;/purchase-orders&gt;</code></pre>
<p>Notice that in version 2 of the API the all-purchase-orders-for-customer resource is no longer exposed in any way. As a human you might guess that it still exists, and indeed it would need to in order to handle requests to version 1 of the API. However, a version 2 consumer will never make a request to that resource because it is not mentioned in the version 2 representations. Indeed, any requests for the all-purchase-orders-for-customer by a version 2 consumer would be met with a <code>406 Not Acceptable</code> response because it is not part of the version 2 API.</p>
<h3 id='wrap_up'>Wrap up</h3>
<p>Toward the end Mr. Dubray gets into full rant mode with these bits,</p>
<blockquote>
<p>You will soon start realizing that resources do have a state that is independent of the &#8220;application&#8221; since by definition a resource can participate in multiple &#8220;applications&#8221;. This is the essence of SOA, i.e. the essence of reuse.</p>
</blockquote>
<p>Resources certainly may participate in multiple &#8220;applications&#8221;. There is nothing in the REST principles that prevent that. I don&#8217;t really claim to be an SOA expert. I just make systems work using REST principles. So far I have not found a problem reusing my resources in multiple applications. In fact, REST seems to excel at that very thing.</p>
<blockquote>
<p>At least, some of the MORCs <span>Member Of the REST Community</span> could have the courtesy to acknowledge that they are indeed building a programming model on top of REST, that this programming model needs clear semantics and that these semantics are not intrinsically part of REST (nor always RESTful).</p>
</blockquote>
<p>I, for one, will readily acknowledge that we have built, and are continuing to build, programming models on top of REST. REST is merely a set of principles, articulated as constraints, that facilitate the creation of useful network based architectures. I would be very surprised if many in the REST community would disagree with me. These programming models do, for the most part, adhere to the REST principles.</p>
<p>Building REST/HTTP web services is certainly not fully understood yet. That does not make it special, hardly any sort of system design or architecture is fully understood. However, REST seems, to me at least, to be a better fit for today&#8217;s applications and technologies than any of the alternatives.</p>
<hr />
<h4 id='related_posts'>Related Posts</h4>
<p>If you&#8217;re interested in REST/HTTP service versioning be sure not to miss the <a href='/blog/tag/rest-versioning/'>rest of the series.</a></p>
]]></content:encoded>
			<wfw:commentRss>http://barelyenough.org/blog/2008/05/resthttp-service-versioning-reponse-to-jean-jacques-dubray/feed/</wfw:commentRss>
		<slash:comments>15</slash:comments>
		</item>
		<item>
		<title>Versioning REST Web Services (Tricks and Tips)</title>
		<link>http://barelyenough.org/blog/2008/05/versioning-rest-web-services-tricks-and-tips/</link>
		<comments>http://barelyenough.org/blog/2008/05/versioning-rest-web-services-tricks-and-tips/#comments</comments>
		<pubDate>Tue, 13 May 2008 20:47:56 +0000</pubDate>
		<dc:creator>Peter Williams</dc:creator>
				<category><![CDATA[Software Development]]></category>
		<category><![CDATA[Rails]]></category>
		<category><![CDATA[REST]]></category>
		<category><![CDATA[rest-versioning]]></category>

		<guid isPermaLink="false">http://pezra.barelyenough.org/blog/?p=336</guid>
		<description><![CDATA[In my previous post on this subject I described an approach to versioning the API of a REST/HTTP web service. This approach has significant advantages over the approach that is currently most common (i.e. embedding a version token in the URL). However, it does have some downsides. This post is an attempt to outline those [...]]]></description>
			<content:encoded><![CDATA[<p>In my <a href='http://pezra.barelyenough.org/blog/2008/05/versioning-rest-web-services/'>previous post on this subject</a> I described an approach to versioning the API of a REST/HTTP web service. This approach has significant advantages over the approach that is currently most common (i.e. embedding a version token in the URL). However, it does have some downsides. This post is an attempt to outline those and to present some ways to mitigate the negative impacts.</p>
<h3 id='nonstandard_mime_media_types'>Nonstandard MIME media types</h3>
<p>Using content negotiation to manage versions requires, by definition, the introduction of nonstandard media types. There is really no way around this. I personally don&#8217;t feel this is a Bad Thing. The new, nonstandard, media types do a much better job describing the sort of media the client is requesting. It does, however, mean that browsers &#8211; and perhaps some HTTP tools &#8211; will work less well with the web service.</p>
<p>The browser not working is a pretty big issue. They are almost certainly not the target consumer of the services, but having the browser not work raises the level of effort for exploring the API. If you have created a cool new service you want as few barriers to entry as possible. Personally, I always use <a href='#curl'>curl</a> when I am exploring but I know several people who would prefer to use a browser.</p>
<p>Unfortunately, I don&#8217;t really have a great general solution for browsers. That being said, in many situations a much can be done to make life better. For example, if the resources in question do not have HTML representations you could serve the current preferred format with a generic content type that browsers can render &#8211; e.g. <code>text/plain</code> or <code>application/xml</code> &#8211; to browsers.</p>
<h3 id='curl_'>Curl <a id='curl' /></h3>
<p>One advantage of having the version token directly in the URL is that it makes it <em>really</em> easy to use <a href='http://curl.haxx.se/'>curl</a> against the service. By default curl makes requests with the Accept header field set to <code>*/*</code>. For a reasonably designed service this would result in a response in the current preferred format. If you want to change to Accept header you need to invoke curl like this</p>
<pre><code>curl --header &#39;Accept: application/vnd.foo.myformat-v1+xml&#39; http://api.example/hello-world</code></pre>
<p>That is not too horrible, really. It is a bit much to type all the time, but I have curl rc files for all the formats I deal with on a daily basis. If your service is implemented in Rails there is an even easier way. With Rails you give each format you support a short name that may be used as an &#8220;extension&#8221; for URLs. For example, if we define the short name for <code>application/vnd.foo.myformat-v1+xml</code> to be <code>mf1</code> we can say this</p>
<pre><code>curl http://api.example/hello-world.mf1</code></pre>
<p>That is equivalent, from the point of view of a Rails based service, to the previous example. I imagine similar functionality could be implemented in most web frameworks. This effectively puts you back to having the version embedded in the URL, which is convenient for debugging and exploration. (It is still unsuitable for production use, though, for all the same reasons as other approaches to embedding the version in the URL.)</p>
<h3 id='nonobviousness'>Nonobviousness</h3>
<p>Another potential downside of using content negotiated versioning is that the various versions my be less discoverable, compared to a version-in-the-URL approach. I am not entirely sure this is true &#8211; after all there is a version token in the media type &#8211; but if it is true it would be a Good Thing.</p>
<p>Do you really want people &#8220;discovering&#8221; a version of the API that was deprecated a year ago? I think it might be better, in either approach, to use version tokens that are not readily guessable. Obviously, previous versions of and API will be documented and remain accessible, but raising some barriers to entry on depreciated parts of a system seems appropriate to me.</p>
<h3 id='unfamiliarity'>Unfamiliarity</h3>
<p>This may be the biggest issue of all. People are just not very familiar, and therefore comfortable, with content negotiation. This in spite of the fact that it has been a fundamental part of HTTP since forever. I think this features obscurity is waning now, though, because it is such a powerful feature.</p>
<p>Two years ago <a href='http://www.loudthinking.com/arc/000572.html'>Rails got content negotiation support</a>. (That link seems to be broken at the moment. You can see part of the post I am talking about by going <a href='http://www.loudthinking.com/arc/2006_04.html'>here</a> and searching for &#8220;The Accept header&#8221;.) As frameworks like Rails keep adding and improving their support for this powerful feature the community of developers will become more familiar and comfortable with it. What is needed now is more education in the community on how best to utilize this feature.</p>
<hr />
<h4 id='related_posts'>Related Posts</h4>
<p>If you&#8217;re interested in REST/HTTP service versioning be sure not to miss the <a href='/blog/tag/rest-versioning/'>rest of the series.</a></p>
]]></content:encoded>
			<wfw:commentRss>http://barelyenough.org/blog/2008/05/versioning-rest-web-services-tricks-and-tips/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>Versioning REST Web Services</title>
		<link>http://barelyenough.org/blog/2008/05/versioning-rest-web-services/</link>
		<comments>http://barelyenough.org/blog/2008/05/versioning-rest-web-services/#comments</comments>
		<pubDate>Mon, 12 May 2008 05:59:37 +0000</pubDate>
		<dc:creator>Peter Williams</dc:creator>
				<category><![CDATA[Software Development]]></category>
		<category><![CDATA[REST]]></category>
		<category><![CDATA[rest-versioning]]></category>

		<guid isPermaLink="false">http://pezra.barelyenough.org/blog/?p=335</guid>
		<description><![CDATA[Managing changes to APIs is hard. That is no surprise to anyone who has ever maintained an API of any sort. Web services, being a special case of API, are susceptible to many of the difficulties around versioning as other types of APIs. For HTTP based REST style web services the combination of resources and [...]]]></description>
			<content:encoded><![CDATA[<p>Managing changes to APIs is hard. That is no surprise to anyone who has ever maintained an API of any sort. Web services, being a special case of API, are susceptible to many of the difficulties around versioning as other types of APIs. For HTTP based REST style web services the combination of resources and content negotiation can be used to mitigate most of the issues surrounding API versioning.</p>
<p>Let&#8217;s assume you have a REST/HTTP web service that has some account resources. Say you can make a request like this:</p>
<pre><code>===&gt;
GET /accounts/3 HTTP/1.1
Accept: application/vnd.mycompany.myapp+xml
&lt;===
HTTP/1.1 200 OK
Content-Type: application/vnd.mycompany.myapp+xml

&lt;account&gt;
  &lt;name&gt;Inigo Montoya&lt;/name&gt;
&lt;/account&gt;</code></pre>
<p>First, you probably noticed that my example uses a <a href='http://tools.ietf.org/html/rfc4288#section-3.2'>vendor MIME media type</a> to describe the representation. Using a more generic MIME media type like <code>application/xml</code> is much more common, at least in my experience. Using generic media types is perfectly legal but a bit silly. You are not really asking for any old XML document, but rather an XML document that has a quite specific schema. Aside from my idealistic rantings, using a specific media type has some strong practical benefits which are at the core of this post.</p>
<h2 id='backwards_compatible_changes'>Backwards compatible changes</h2>
<p>Often changes will need to be made to expose new behavior of the system that do not negatively impact correctly implemented clients. Say, for example, you want to start tracking email address for accounts. If the <code>application/vnd.mycompany.myapp+xml</code> format documentation is clear that elements that are not recognized should be ignored you can simply add a email element to the account representation.</p>
<pre><code>&lt;account&gt;
  &lt;name&gt;Inigo Montoya&lt;/name&gt;
  &lt;email-address&gt;mailto:prepare-to-die@youkilledmyfather.example&lt;/email-address&gt;
&lt;/account&gt;</code></pre>
<p>Any client that was created before the addition of the email element will simply ignore it&#8217;s presence. Problem solved.</p>
<h2 id='incompatible_changes'>Incompatible changes</h2>
<p>Unfortunately, not all changes can be implemented in a way that is backwards compatible. For example, a couple of months after adding email to accounts the sales team sign a deal for 1 bazillion dollars. But the new customer demands that each account be allowed to have more than one email address. After thinking for a while, you decide that the best way to expose that is by changing the account representation as follows.</p>
<pre><code>&lt;account&gt;
  &lt;name&gt;Inigo Montoya&lt;/name&gt;
  &lt;email-addresses&gt;
    &lt;email-address priority=&#39;1&#39;&gt;mailto:prepare-to-die@youkilledmyfather.example&lt;/email-address&gt;
    &lt;email-address priority=&#39;2&#39;&gt;mailto:vengeance@youkilledmyfather.example&lt;/email-address&gt;
  &lt;email-address&gt;
&lt;/account&gt;</code></pre>
<p>That, of course, will break any clients that are expecting the old format &#8211; so pretty much all of them. This is a place where we can bring content negotiation to bear. You can simply define a new media type &#8211; say <code>application/vnd.mycompany.myapp-v2+xml</code> &#8211; and associate new multi-email format with it. Clients can then request whichever format they want. Older clients don&#8217;t know the new media type so they get served the older single email format.</p>
<pre><code>===&gt;
GET /accounts/3 HTTP/1.1
Accept: application/vnd.mycompany.myapp+xml
&lt;===
HTTP/1.1 200 OK
Content-Type: application/vnd.mycompany.myapp+xml

&lt;account&gt;
  &lt;name&gt;Inigo Montoya&lt;/name&gt;
  &lt;email-address&gt;mailto:prepare-to-die@youkilledmyfather.example&lt;/email-address&gt;
&lt;/account&gt;</code></pre>
<p>Newer clients do know the new media type so they can have access to the new functionality.</p>
<pre><code>===&gt;
GET /accounts/3 HTTP/1.1
Accept: application/vnd.mycompany.myapp-v2+xml
&lt;===
HTTP/1.1 200 OK
Content-Type: application/vnd.mycompany.myapp-v2+xml

&lt;account&gt;
  &lt;name&gt;Inigo Montoya&lt;/name&gt;
  &lt;email-addresses&gt;
    &lt;email-address priority=&#39;1&#39;&gt;mailto:prepare-to-die@youkilledmyfather.example&lt;/email-address&gt;
    &lt;email-address priority=&#39;2&#39;&gt;mailto:vengeance@youkilledmyfather.example&lt;/email-address&gt;
  &lt;email-address&gt;
&lt;/account&gt;</code></pre>
<p>Everyone gets what they need. Easy as pie.</p>
<h2 id='alternate_approaches'>Alternate approaches</h2>
<p>The most commonly proposed approach for versioning REST/HTTP web service interfaces today seems to be to mutilate the URIs by inserting a version. For example,</p>
<pre><code>http://foo.example/api/v1/accounts/3</code></pre>
<p>I really hate this approach as it implies that an account in one version of the API is really a different resource than the account in a different version of the API.</p>
<p>It also forces clients into a nasty choice, either support multiple versions of the API simultaneously or break one of the core constrains of REST. For example, say a client exists for the v1 API that saves references (URIs that include the version indicator) to accounts. Some time later the client is updated to support the new version of the API. In this situation the The client can support both versions of the API simultaneously because all the previously stored URIs point at the old version of the API or it has to mung all the URIs it has stored to the point at the new API. Munging all the URIS breaks the <a href='http://pezra.barelyenough.org/blog/2007/05/hypermedia-as-the-engine-of-application-state/'>HATEOAS</a> constraint of REST and supporting multiple versions of the API is a maintenance nightmare.</p>
<h2 id='conclusion'>Conclusion</h2>
<p>Changes to REST/HTTP web service interfaces come it three basic flavors, changes to the properties associated with a type of resource, additions of new types of resources and deprecation of obsolete types of resources. If you are following the <a href='http://pezra.barelyenough.org/blog/2007/05/hypermedia-as-the-engine-of-application-state/'>HATEOAS</a> constraint of REST the approach described here can be used to safely handle all three scenarios.</p>
<p>This approach does lead to media types being created, but media types are cheap so we can &#8211; and should &#8211; have as many as we need. Used properly, content negotiation can be used to solve the problems related to versioning a REST/HTTP web service interface.</p>
<hr />
<h4 id='related_posts'>Related Posts</h4>
<p>If you&#8217;re interested in REST/HTTP service versioning be sure not to miss the <a href='/blog/tag/rest-versioning/'>rest of the series.</a></p>
]]></content:encoded>
			<wfw:commentRss>http://barelyenough.org/blog/2008/05/versioning-rest-web-services/feed/</wfw:commentRss>
		<slash:comments>59</slash:comments>
		</item>
	</channel>
</rss>

