<?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>Alexandre Martins &#187; RESTful Web Services</title>
	<atom:link href="http://blog.m.artins.net/category/restful-web-services/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.m.artins.net</link>
	<description>On Agile Software Development</description>
	<lastBuildDate>Thu, 12 Aug 2010 20:09:21 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>RESTful Web Services: Preventing Race Conditions</title>
		<link>http://blog.m.artins.net/restful-web-services-preventing-race-conditions/</link>
		<comments>http://blog.m.artins.net/restful-web-services-preventing-race-conditions/#comments</comments>
		<pubDate>Fri, 05 Mar 2010 20:41:20 +0000</pubDate>
		<dc:creator>Alexandre Martins</dc:creator>
				<category><![CDATA[RESTful Web Services]]></category>
		<category><![CDATA[REST]]></category>

		<guid isPermaLink="false">http://blog.m.artins.net/?p=279</guid>
		<description><![CDATA[One of the core premisses of RESTful web services is that HTTP should be seen as an application protocol rather than just a transport protocol. It comprises a whole bunch of semantics that allows us to build robust distributed systems. And for some cases, when multiple consumers manipulate the same resource, therefore changing its state, [...]]]></description>
			<content:encoded><![CDATA[<p>One of the core premisses of RESTful web services is that HTTP should be seen as an application protocol rather than just a transport protocol. It comprises a whole bunch of semantics that allows us to build robust distributed systems. And for some cases, when multiple consumers manipulate the same resource, therefore changing its state, the solution should be robust enough to prevent the system to get into a <a href="http://en.wikipedia.org/wiki/Race_condition#Computing">race condition</a>.</p>
<h3>But how HTTP could prevent that?</h3>
<p>HTTP provides a simple but powerful mechanism for aligning resource states by making use of <a href="http://en.wikipedia.org/wiki/HTTP_ETag">entity tag or ETag</a> and <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html">conditional request headers</a>. An <span style="font-family: Courier New; font-size: 12px;">ETag</span> is anything that uniquely identifies an entity, such as the ID associated with a persisted resource, a checksum of the entity headers and body, etc. If this resource changes—that is, when one or more of its headers, or its entity body, changes—then the entity tag changes accordingly, reflecting this new resource state.</p>
<p>When a response contains an <span style="font-family: Courier New; font-size: 12px;">ETag</span> associated to a resource state and you want to continue working with this same resource, it's recommended to use this tag in subsequent requests (called <em>conditional requests</em>), otherwise the resource state might eventually become out of sync with service one, returning something like a <span style="font-family: Courier New; font-size: 12px;">409 Conflict</span>. </p>
<p>Conditional requests happens when the current <span style="font-family: Courier New; font-size: 12px;">ETag</span> is supplied to a <em>conditional request header</em>, such as <span style="font-family: Courier New; font-size: 12px;">If-Match</span> or <span style="font-family: Courier New; font-size: 12px;">If-None-Match</span>, when user is requesting to update a resource for example. The service will then check the precondition, by comparing the current resource <span style="font-family: Courier New; font-size: 12px;">ETag</span> with the one provided in the request. If it's satisfied than the server proceeds and process the request, otherwise it concludes that the resource has changed and responds with a <span style="font-family: Courier New; font-size: 12px;">412 Precondition Failed</span>.</p>
<h3>Example</h3>
<p>Given an online shop for home goods, where two people— <strong>Admin1</strong> and <strong>Admin2</strong> —are responsible for administrating its contents. In our scenario both administrators are trying to change the state of the same product (the Weber BBQ), around the same time. <strong>Admin1</strong> wants to lower the product price down to $300.00 and <strong>Admin2</strong> wants to change its state to "Not Available". Firstly, both administrators <span style="font-family: Courier New; font-size: 12px;">GET</span> the current product state independently of one another by doing the following request: </p>
<pre style="background-color: #FFFFE3; border-left: solid gray 4px; padding: 8px; margin-bottom: 10px; font-family: Courier New; font-size: 12px;">
GET /product/1 HTTP/1.1
Host: myshop.com
</pre>
<p>Returning the following resource (product) as response. Note that the service's response contains an <span style="font-family: Courier New; font-size: 12px;">ETag</span> header.</p>
<pre style="background-color: #FFFFE3; border-left: solid gray 4px; padding: 8px; margin-bottom: 10px; font-family: Courier New; font-size: 12px;">
HTTP/1.1 200 OK
Content-Length: 265
Content-Type: application/xml
ETag: "686897696a7c876b7e"

&lt;product&gt;
  &lt;name&gt;Weber Family BBQ&lt;/name&gt;
  &lt;description&gt;Great for parties and cooks a neat roast too.&lt;/description&gt;
  &lt;price&gt;$399.00&lt;/price&gt;
  &lt;status&gt;In Stock&lt;/status&gt;
&lt;/product&gt;
</pre>
<p>When <strong>Admin1</strong> does a conditional <span style="font-family: Courier New; font-size: 12px;">PUT</span>, including an <span style="font-family: Courier New; font-size: 12px;">If-Match</span> header with the <span style="font-family: Courier New; font-size: 12px;">ETag</span> value from the previous <span style="font-family: Courier New; font-size: 12px;">GET</span>.</p>
<pre style="background-color: #FFFFE3; border-left: solid gray 4px; padding: 8px; margin-bottom: 10px; font-family: Courier New; font-size: 12px;">
PUT /product/1 HTTP/1.1
Host: myshop.com
If-Match: "686897696a7c876b7e"

&lt;product&gt;
  &lt;name&gt;Weber Family BBQ&lt;/name&gt;
  &lt;description&gt;Great for parties and cooks a neat roast too.&lt;/description&gt;
  &lt;price&gt;$300.00&lt;/price&gt;
  &lt;status&gt;In Stock&lt;/status&gt;
&lt;/product&gt;
</pre>
<p>And as the product state hasn't changed since the last request, then the request is thus successful! Notice that the response returns an updated <span style="font-family: Courier New; font-size: 12px;">ETag</span> value, reflecting the new product state.</p>
<pre style="background-color: #FFFFE3; border-left: solid gray 4px; padding: 8px; margin-bottom: 10px; font-family: Courier New; font-size: 12px;">
HTTP/1.1 204 No Content
ETag: "616898r96a8cy86b8eee11"
</pre>
<p>Little time after <strong>Admin1</strong> has updated the product, <strong>Admin2</strong> does another <span style="font-family: Courier New; font-size: 12px;">PUT</span> to the same product, including the same <span style="font-family: Courier New; font-size: 12px;">If-Match</span> header with the <span style="font-family: Courier New; font-size: 12px;">ETag</span> value from the <span style="font-family: Courier New; font-size: 12px;">GET</span> request.</p>
<pre style="background-color: #FFFFE3; border-left: solid gray 4px; padding: 8px; margin-bottom: 10px; font-family: Courier New; font-size: 12px;">
PUT /product/1 HTTP/1.1
Host: myshop.com
If-Match: "686897696a7c876b7e"

&lt;product&gt;
  &lt;name&gt;Weber Family BBQ&lt;/name&gt;
  &lt;description&gt;Great for parties and cooks a neat roast too.&lt;/description&gt;
  &lt;price&gt;$399.00&lt;/price&gt;
  &lt;status&gt;Not Available&lt;/status&gt;
&lt;/product&gt;
</pre>
<p>The service then determines that someone is trying to change the same product, using an out-of-date resource representation (<span style="font-family: Courier New; font-size: 12px;">ETag</span>s are different!), and responds with a <span style="font-family: Courier New; font-size: 12px;">412 Precondition Failed</span> code. No race conditions whatsoever!</p>
<pre style="background-color: #FFFFE3; border-left: solid gray 4px; padding: 8px; margin-bottom: 10px; font-family: Courier New; font-size: 12px;">
HTTP/1.1 412 Precondition Failed
</pre>
<h3>Conclusion</h3>
<p>Although <span style="font-family: Courier New; font-size: 12px;">ETag</span>s and <em>conditional request headers</em> make up a powerful mechanism for dealing with concurrency, one thing to keep in mind is that, depending on the amount of computation performed by the server to generate an <span style="font-family: Courier New; font-size: 12px;">ETag</span>, response times might increase considerably. So use it only if you need it!</p>
<p><cite>Special thanks to <a href="http://jim.webber.name/">Jim Webber</a> for helping me with this post. For more information on RESTful Web Services, check out his latest book (written together with <a href="http://savas.me/">Savas Parastatidis</a> and <a href="http://iansrobinson.com/">Ian Robinson</a>)— <a href="http://www.amazon.com/gp/product/0596805829">REST in Practice: Hypermedia and Systems Architecture</a>.</cite></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.m.artins.net/restful-web-services-preventing-race-conditions/feed/</wfw:commentRss>
		<slash:comments>14</slash:comments>
		</item>
	</channel>
</rss>
