<?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>subbu.org &#187; REST</title>
	<atom:link href="http://www.subbu.org/blog/category/rest/feed" rel="self" type="application/rss+xml" />
	<link>http://www.subbu.org</link>
	<description></description>
	<lastBuildDate>Sat, 28 Jan 2012 18:26:03 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>ql.io: Consuming HTTP at Scale</title>
		<link>http://www.subbu.org/blog/2012/01/ql-io-consuming-http-at-scale</link>
		<comments>http://www.subbu.org/blog/2012/01/ql-io-consuming-http-at-scale#comments</comments>
		<pubDate>Wed, 25 Jan 2012 01:08:03 +0000</pubDate>
		<dc:creator>Subbu Allamaraju</dc:creator>
				<category><![CDATA[HTTP]]></category>
		<category><![CDATA[REST]]></category>
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.subbu.org/?p=1719</guid>
		<description><![CDATA[Slides from my workshop on ql.io at the Node Summit. ql.io: Consuming HTTP at Scale View more presentations from Subbu Allamaraju]]></description>
			<content:encoded><![CDATA[<p></p><div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.subbu.org%2Fblog%2F2012%2F01%2Fql-io-consuming-http-at-scale"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.subbu.org%2Fblog%2F2012%2F01%2Fql-io-consuming-http-at-scale&amp;style=normal&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p>Slides from my workshop on ql.io at the Node Summit.</p>
<div style="width:425px" id="__ss_11244206"> <strong style="display:block;margin:12px 0 4px"><a href="http://www.slideshare.net/sallamar/qlio-consuming-http-at-scale" title="ql.io: Consuming HTTP at Scale " target="_blank">ql.io: Consuming HTTP at Scale </a></strong> <iframe src="http://www.slideshare.net/slideshow/embed_code/11244206" width="425" height="355" frameborder="0" marginwidth="0" marginheight="0" scrolling="no"></iframe>
<div style="padding:5px 0 12px"> View more <a href="http://www.slideshare.net/" target="_blank">presentations</a> from <a href="http://www.slideshare.net/sallamar" target="_blank">Subbu Allamaraju</a> </div>
</p></div>
]]></content:encoded>
			<wfw:commentRss>http://www.subbu.org/blog/2012/01/ql-io-consuming-http-at-scale/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Measuring REST</title>
		<link>http://www.subbu.org/blog/2011/08/measuring-rest-2</link>
		<comments>http://www.subbu.org/blog/2011/08/measuring-rest-2#comments</comments>
		<pubDate>Sun, 21 Aug 2011 16:48:17 +0000</pubDate>
		<dc:creator>Subbu Allamaraju</dc:creator>
				<category><![CDATA[HTTP]]></category>
		<category><![CDATA[REST]]></category>

		<guid isPermaLink="false">http://www.subbu.org/?p=1531</guid>
		<description><![CDATA[These are the slides from my talk yesterday at restfest.]]></description>
			<content:encoded><![CDATA[<p></p><div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.subbu.org%2Fblog%2F2011%2F08%2Fmeasuring-rest-2"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.subbu.org%2Fblog%2F2011%2F08%2Fmeasuring-rest-2&amp;style=normal&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p>These are the slides from my talk yesterday at restfest.</p>
<p><iframe src="http://docs.google.com/viewer?url=https%3A%2F%2Fgithub.com%2Fs3u%2Ftalks%2Fraw%2Fmaster%2Fmeasuring-rest-restfest-2011.pdf&#038;embedded=true" width="600" height="470" style="border: none;"></iframe></p>
]]></content:encoded>
			<wfw:commentRss>http://www.subbu.org/blog/2011/08/measuring-rest-2/feed</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>Performance of RESTful Apps</title>
		<link>http://www.subbu.org/blog/2011/03/performance-of-restful-apps</link>
		<comments>http://www.subbu.org/blog/2011/03/performance-of-restful-apps#comments</comments>
		<pubDate>Fri, 04 Mar 2011 19:08:43 +0000</pubDate>
		<dc:creator>Subbu Allamaraju</dc:creator>
				<category><![CDATA[HTTP]]></category>
		<category><![CDATA[REST]]></category>
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.subbu.org/?p=1416</guid>
		<description><![CDATA[A while ago I showed how chatty some well-known apps are on my iPhone. But this issue is neither new nor unique to apps on phones and similar devices. Efficient data retrieval from distributed/decentralized servers is a well-recognized problem in distributed computing. For instance, in the abstract of his November 1994 paper A Note on [...]]]></description>
			<content:encoded><![CDATA[<p></p><div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.subbu.org%2Fblog%2F2011%2F03%2Fperformance-of-restful-apps"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.subbu.org%2Fblog%2F2011%2F03%2Fperformance-of-restful-apps&amp;style=normal&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p>A while ago I <a href="http://www.subbu.org/blog/2011/01/chatty-apps">showed</a> how chatty some well-known apps are on my iPhone. But this issue is neither new nor unique to apps on phones and similar devices. Efficient data retrieval from distributed/decentralized servers is a well-recognized problem in distributed computing. For instance, in the abstract of his November 1994 paper <a href="http://labs.oracle.com/techrep/1994/abstract-29.html">A Note on Distributed Computing</a>, <a href="http://www.eecs.harvard.edu/~waldo/">Jim Waldo</a> notes the following (emphasis mine).</p>
<blockquote>
<p>We argue that objects that interact in a distributed system need to be dealt with in ways that are intrinsically different from objects that interact in a single address space. These differences are required because distributed systems require that the programmer be aware of <strong>latency</strong>, have a different model of <strong>memory access</strong>, and take into account issues of <strong>concurrency</strong> and <strong>partial failure</strong>.</p>
</blockquote>
<p><span id="more-1416"></span></p>
<p>Most front-end developers by now know and follow the <a href="http://developer.yahoo.com/performance/rules.html">best practices</a> that Yahoo!&#8217;s <a href="http://developer.yahoo.com/performance/">Exceptional Performance</a> team documented a few years ago. However, the REST community may have missed the bus and has some catching up to do. Performance of RESTful Apps is not one of the most frequently talked about topics online or in print. From talking to various teams, it often seems that a great deal of time is spent on <a href="http://my.safaribooksonline.com/9780596809140/75">URI</a>/<a href="http://my.safaribooksonline.com/9780596809140/45">representation</a> design, schemas, use of the <a href="http://my.safaribooksonline.com/9780596809140/1">uniform interface</a> for CRUD, using the <a href="http://my.safaribooksonline.com/9780596809140/87">hypertext constraint</a> etc. No doubt &#8211; these topics are all very important, but understanding and accounting for the performance characteristics in the design and implementation of server and client apps is no less crucial.</p>
<p>Here are some techniques to help build high-performance RESTful apps.</p>
<h2>Composites for Performance</h2>
<p>The best of all web performance techniques is to <a href="http://developer.yahoo.com/performance/rules.html#num_http">minimize the number of HTTP requests</a>. However, RESTful Apps rarely follow this practice. This difference stems from how each side sees resources.</p>
<p><img src="http://www.subbu.org/uploads/2011/03/fe-vs-apis.png" alt="Front-end vs APIs/services"/></p>
<p>On one side, front-end folks optimize their servers to serve bulk representations for CSS, JavaScript or image sprites, or even <a href="http://googlecode.blogspot.com/2010/11/instant-previews-under-hood.html">data URIs for images</a> to reduce the number of HTTP requests and thereby latency. On the front-end, most resources are in fact composites.</p>
<p>On the other side, API/service developers prefer <em>clean looking</em> resources and URIs (shown on the right side above). Though this can lead to chatty network usage, there is one specific advantage in offering a set of resources that are independent and less coupled with other resources &#8211; <strong>it leaves room for clients to innovate</strong>. It lets them combine data from multiple resources in numerous ways that the resource developers could not possibly think of.</p>
<p><img src="http://www.subbu.org/uploads/2011/03/apis-possibilities.png" alt="Many possibilities"/></p>
<p>Loose coupling is another benefit of this approach, as clients can evolve rapidly on their own.</p>
<p>The expense is of course latency, particularly when those client apps are not very close to the servers. Each client may need to submit several requests to the server in order get its job done. So, how do we go about fixing this without sacrificing the flexibility of less-coupled resources?  One answer is to use composite resources. See my <a href="http://my.safaribooksonline.com/book/web-development/web-services/9780596809140/identifying-resources/34">RESTful Web Services Cookbook</a> for details.</p>
<p>With a composite, in stead of sending <code>n</code>-number of HTTP requests over <code>1-n</code> connections, the client can open just one TCP connection to send an HTTP request to retrieve the data it needs &#8211; just like a browser getting CSS or Javascript bundles in the front-end. A composite changes a pattern like</p>
<pre><code>GET /something HTTP/1.1
Host: www.example.org

GET /something-else?params HTTP/1.1
Host: www.example.org

GET /some-other-thing-related-to-something?params HTTP/1.1
Host: www.example.org
</code></pre>
<p>to</p>
<pre><code>GET /get-all-things-i-need-about-something?params HTTP/1.1
Host: www.example.org
</code></pre>
<p>Each composite can generate a projection of state required for one or more clients. These composites can be more specialized than the resources they aggregate &#8211; as each composite can cater to particular client needs.</p>
<p><img src="http://www.subbu.org/uploads/2011/03/composite.png" alt="Many possibilities"/></p>
<p>(P.S.: My usage of the term &quot;resource&quot; is not precise here as a &quot;composite&quot; is also a resource.)</p>
<p>This approach also shifts issues related to concurrency (such as ordering of requests based on success or failure), CPU (for generating projections, correlating related data from across representations etc.) and I/O (to fetch back-end resource representations in a serial/parrallel fashion depending on dependencies) workloads from the client to the server.</p>
<p>On the server side, the server hosting composites can also optimize its connection handling to resource servers to reduce TCP handshake and slowstart overhead. For instance, it can maintain pools of persistent/long-lasting connections (e.g., with <code>keep-alive</code>) between servers hosting composites and the resources (shown by bold arrows above).</p>
<p>In this post, I&#8217;m not going to discuss software choices to serve composites, but you may need to account for several features:</p>
<ul>
<li>multi-tenancy or isolation of code execution, configuration and deployment so that different teams can build composites</li>
<li>data or control flow for fetching representations in parallel or sequentially based on inter-dependencies</li>
<li>query languages (such as <a href="http://developer.yahoo.com/yql/console/">YQL</a>) to normalize data formats and to easily create projections</li>
<li>non-blocking or asynchronous I/O to better tackle I/O workloads</li>
</ul>
<p>I&#8217;m personally excited about <a href="http://nodejs.org/">nodejs</a> and async I/O support in Java 7 as both would let us build small and nimble broker apps to serve composites.</p>
<p>Of course &#8211; the idea of a composite is to add an extra layer of indirection on the server side to offset network overhead when performance is at stake. It is not meant to replace loosely coupled resources that can be manipulated using HTTP and linked using hypertext controls like links in representations.</p>
<h2>Better Connection Reuse</h2>
<p>Long-lasting TCP connections help reduce connection-establishment overhead as well as help the TCP stack settle to appropriate congestion window size. Reusing connections is usually trivial, and pooling is often part of client libraries. But there are a few precautions to take at the application level.</p>
<h3>Avoid Explicit Connection Closing</h3>
<pre><code># Don't do this
HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 1234
Connection: close

{ ... body ... }
</code></pre>
<p>The first precaution to take is not to add <code>Connection: close</code> to requests or responses by default. Carelessly adding this header to requests or responses will prevent connection reuse. There better be a good reason to add this header such as a server that can&#8217;t handle too many open connections, or to prevent abuse.</p>
<h3>Avoid Close Delimited Messages</h3>
<pre><code># Avoid this
HTTP/1.1 200 OK
Content-Type: application/json

{ ... body ... }
</code></pre>
<p>Make sure to include <code>Content-Length</code> or use <code>Transfer-Encoding: chunked</code> so that the recipient of a HTTP message can know when one HTTP request/response message ends and when the next one starts. If a response has neither of these two, then the recipient will need to read the stream till the connection is closed, which means that the connection cannot be reused. Close-delimited HTTP request/response messages are bad for performance.</p>
<h3>Read Messages Completely</h3>
<p>Incomplete reads will also prevent reuse of the connection. Incomplete reads usually happen when a client receives an error or a redirect response. These kinds of responses can have a body but clients can determine what to do by just looking at the response line and headers. For instance, a <code>409</code> response may have a body that explains why.</p>
<pre><code>HTTP/1.1 409 Conflict
Content-Type: text/html
Content-Length: 1234

&lt;html&gt; ... &lt;/html&gt;
</code></pre>
<p>But not reading the body from the connection my prevent reuse in some frameworks &#8211; Java is <a href="http://download.oracle.com/javase/1.5.0/docs/guide/net/http-keepalive.html">known</a> for this. Also be wary of libraries that translate <code>4xx</code> and <code>5xx</code> response code into exceptions &#8211; in this case, in addition to catching the exception, the client will need to read the body.</p>
<h3>Tune Idle Connection Timeouts</h3>
<p>Servers and clients usually close idle connections upon a timeout to conserve resources. Settings for idle connection timeout may be hard to find or even not exposed in client/server frameworks. When tuning is possible, ensure that the defaults are reasonable.</p>
<h3>Try Proxies for Long-Haul Traffic</h3>
<p>In some cases a configuration like the following can help:</p>
<p><img src="http://www.subbu.org/uploads/2011/03/proxy-short-lived.png" alt="Proxies for short-lived apps"/></p>
<ul>
<li>Client apps that are short-living (like an app on a mobile/tablet or even on desktops), and hence connections can&#8217;t be persistent. Instead, the proxy can keep connections persistent which limits connection establishment cost to the first leg from client app to the nearest proxy.</li>
<li>Client apps that can&#8217;t maintain too many persistent connections &#8211; which is still the case for browsers today &#8211; though it is slowly changing.</li>
</ul>
<p>Of course, this approach also lets the server <a href="http://www.mnot.net/blog/2006/05/16/web_2_caching">distribute</a> responses to caches on those proxies to further reduce network cost. Many variations of this approach are possible depending on how your servers are distributed and how far are client apps from servers. If you&#8217;re new to the idea of REST and are still wondering why HTTP&#8217;s uniform interface is such a big deal, here is why &#8211; once you implement HTTP reasonably correctly, you can reconfigure servers, proxies and caches as necessary without code changes.</p>
<h2>Progressive Serving of Representations</h2>
<p>Sometimes it is not the network, but generating a response is the bottleneck. This is particularly true for composite resources or resources that rely on a number of data sources to generate a response to the client. The typical flow in such cases is as follows:</p>
<ul>
<li>read the request data such as the path and query string</li>
<li>decide what to fetch</li>
<li>fetch data from each dependent source in sequence or concurrently to the extent possible (which depends on dependencies)</li>
<li>prepare data for the response</li>
<li>write the data to the response</li>
</ul>
<p>Of these steps, when I/O for dependent sources is done sequentially, the server takes at least <code>n*t</code> time to generate a response. If all the I/O can be done in parallel, it takes <code>max(t)</code> amount of time, i.e, it performs at least as slow as the slowest source.</p>
<p>On the front-end side, when it takes time to generate a page, a common practice is to turn to <code>XMLHttpRequest</code> or <code>iframe</code>s to split the page into fragments and defer loading of slower parts of the page. Both these techniques potentially use additional connections. In a multi-tiered setup, this causes a flood of new requests from the browser to front-end servers, and from there to backend servers and so on. This also introduces new state management and security problems as the server may need to push state first to the browser only to get it back via <code>XMLHttpRequest</code> immediately.</p>
<p>An alternative is to progressively render the page over a single connection. In this case, the flow would be</p>
<ul>
<li>read the request data such as the path and query string</li>
<li>decide what to fetch</li>
<li><em>fetch data from fast sources</em></li>
<li><em>initiate requests for slow sources</em></li>
<li><em>serve partial page based on response from fast sources</em></li>
<li><em>as and when a slow source responds, prepare a partial response and write to the client</em></li>
<li><em>after all the sources respond (or after some timeout), write additional chunks and finally end the page</em></li>
</ul>
<p>Here, by &#8220;chunk&#8221; I mean &#8220;part of a message&#8221; and not an HTTP chunk.</p>
<p>The goal of this technique is to reduce user-perceived latency without using more network connections from the browser. In this flow, browser makes an HTTP request to the front-end server which writes snippets of markup and script over a period of time before ending the response. Since the server does not know the <code>Content-Length</code> of the page, it would use <code>chunked</code> transfer encoding where end of response is triggered by a zero-sized chunk.</p>
<p>This is called &#8220;progressive rendering&#8221;. This technique is well-known in front-end circles and Facebook calls this technique <a href="http://www.facebook.com/notes/facebook-engineering/bigpipe-pipelining-web-pages-for-high-performance/389414033919">BigPipe</a>. Progressive rendering depends on two things:</p>
<ul>
<li>Server being able to write chunks over lasting connections &#8211; asynchronous I/O based servers like <a href="http://nodejs.org/">nodejs</a> are very attractive for this (see my nodejs <a href="http://www.subbu.org/blog/2010/07/bigpipe-done-in-node-js">example</a> or <a href="http://www.olympum.com">Bruno</a>&#8216;s <a href="http://www.olympum.com/java/facebook-bigpipe-in-an-async-servlet/">example</a> using continuations).</li>
<li>Clients being able to process response as it arrives &#8211; in Javascript capable browsers, this capability is already present.</li>
</ul>
<p>We can apply this technique for non-front-end resources as well provided (a) it is possible to retrieve data from fast sources before slow resources, and (b) data from fast sources is meaningful to clients. For instance, think of a personalized product resource that includes data about a product plus IDs, links, and brief summaries of related products. In this case, product data can be looked up from storage under a near-constant time (say, about 20 milliseconds) while finding related products may involve performing some computations on the user profile, past purchase history and other derived data which can be time consuming &#8211; say, taking up to 500 milliseconds. Here is an example of a progressive representation of such a product resource.</p>
<pre><code>HTTP/1.1 200 OK
Content-Type: multipart/mixed; boundary=abcdef
Transfer-Encoding: chunked

--abcdef
Content-Type: application/json

{ ... product data here ... }

--abcdef
Content-Type: application/json

{ ... related products here ... }
--abcdef--
</code></pre>
<p>In this example I used a multipart media type as it provides a visible boundary between different portions of the representations, and the client can read the representation part by part. </p>
<p>If the client is a front-end app that generates an HTML product page for browsers, it can progressively render the product page as soon as it receives the first part, and then render markup for list of related products when the second part arrives.</p>
<pre><code>HTTP/1.1 200 OK
Content-Type: text/html
Transfer-Encoding: chunked

&lt;html&gt;
  &lt;head&gt;...&lt;/head&gt;
  &lt;body&gt;
    ... HTML for the product data ...

    &lt;div id="related"&gt;&lt;/div&gt;

    &lt;!-- script for related products (some milliseconds later) --&gt;
    &lt;script&gt; // update related div ...&lt;/script&gt;
  &lt;/body&gt;
&lt;/html&gt;
</code></pre>
<p>This shows how progressive generation of arbitrary representations can be combined with progressive serving of the front-end to reduce perceived latency.</p>
<h2>Epilogue</h2>
<p>One of the patterns to notice from this post is that design considerations between HTML serving front-end apps and JSON/XML/whatever-speaking RESTful apps are not entirely different. Both rely on the same set of core architectural principles such as the uniform interface, visibility, hypertext, and so on. Whatever lessons we learn on the front end are certainly applicable for the so-called API servers.</p>
<p>Finally, it goes without saying that premature optimization is evil. My goal of this post is to point out the techniques you may already have in your toolkit. Apply them based on the need and experimentation.</p>
<p><em>If you find this post useful, try my book: <a href="http://www.amazon.com/gp/product/0596801688?ie=UTF8&#038;tag=cyclogzcom-20&#038;linkCode=as2&#038;camp=1789&#038;creative=390957&#038;creativeASIN=0596801688">RESTful Web Services Cookbook</a>.</em></p>
]]></content:encoded>
			<wfw:commentRss>http://www.subbu.org/blog/2011/03/performance-of-restful-apps/feed</wfw:commentRss>
		<slash:comments>36</slash:comments>
		</item>
		<item>
		<title>Save 60% on RESTful Web Services Cookbook</title>
		<link>http://www.subbu.org/blog/2011/01/save-60-on-restful-web-services-cookbook</link>
		<comments>http://www.subbu.org/blog/2011/01/save-60-on-restful-web-services-cookbook#comments</comments>
		<pubDate>Tue, 18 Jan 2011 22:35:21 +0000</pubDate>
		<dc:creator>Subbu Allamaraju</dc:creator>
				<category><![CDATA[HTTP]]></category>
		<category><![CDATA[REST]]></category>
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.subbu.org/?p=1360</guid>
		<description><![CDATA[O&#8217;Reilly will be offering the ebook version of the RESTful Web Services Cookbook on sale tomorrow (Jan 19, 2011). Here is the scoop I just received from O&#8217;Reilly. Save 60% &#8211; Top 25 of 2010 Best of Ebook Deal of the Day &#8211; http://post.oreilly.com/rd/9z1ztpijtp7meklse9bq1u34nnvf1fdmc1n0battp2g For one day only, you can save 60% on our best [...]]]></description>
			<content:encoded><![CDATA[<p></p><div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.subbu.org%2Fblog%2F2011%2F01%2Fsave-60-on-restful-web-services-cookbook"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.subbu.org%2Fblog%2F2011%2F01%2Fsave-60-on-restful-web-services-cookbook&amp;style=normal&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p>O&#8217;Reilly will be offering the ebook version of the <a href="http://www.restful-webservices-cookbook.org">RESTful Web Services Cookbook</a> on sale tomorrow (Jan 19, 2011). Here is the scoop I just received from O&#8217;Reilly.</p>
<blockquote>
<p>Save 60% &#8211; Top 25 of 2010</p>
<p>Best of Ebook Deal of the Day &#8211; <a href="http://post.oreilly.com/rd/9z1ztpijtp7meklse9bq1u34nnvf1fdmc1n0battp2g">http://post.oreilly.com/rd/9z1ztpijtp7meklse9bq1u34nnvf1fdmc1n0battp2g</a></p>
<p>For one day only, you can save 60% on our best of &#8220;Ebook Deal of the Day&#8221; titles &#8211; the top 25 of 2010. Ebooks from oreilly.com are DRM-free. You get free lifetime access, multiple file formats, and free updates. One day only. Use discount code <strong>DDT25</strong> in the shopping cart. </p>
</blockquote>
]]></content:encoded>
			<wfw:commentRss>http://www.subbu.org/blog/2011/01/save-60-on-restful-web-services-cookbook/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Chatty Apps</title>
		<link>http://www.subbu.org/blog/2011/01/chatty-apps</link>
		<comments>http://www.subbu.org/blog/2011/01/chatty-apps#comments</comments>
		<pubDate>Mon, 17 Jan 2011 23:50:59 +0000</pubDate>
		<dc:creator>Subbu Allamaraju</dc:creator>
				<category><![CDATA[HTTP]]></category>
		<category><![CDATA[REST]]></category>
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.subbu.org/?p=1357</guid>
		<description><![CDATA[We know that the first practice to speed up performance of a site is to minimize the number of HTTP requests. The same should be true for mobile apps too, but the results I find from some of the apps I commonly use on my iPhone show that the apps have not paid enough attention [...]]]></description>
			<content:encoded><![CDATA[<p></p><div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.subbu.org%2Fblog%2F2011%2F01%2Fchatty-apps"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.subbu.org%2Fblog%2F2011%2F01%2Fchatty-apps&amp;style=normal&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p>We know that the first practice to speed up performance of a site is to minimize the number of HTTP requests. The same should be true for mobile apps too, but the results I find from some of the apps I commonly use on my iPhone show that the apps have not paid enough attention to this practice. I used <a href="http://www.charlesproxy.com/">Charles Proxy</a> for my tests. I can not vouch for the correctness of some of the headers reported by this proxy, but the common pattern I noticed is the number of HTTP requests they fire up is not small. This pattern has obvious impact on the user-perceived latency and even battery life.</p>
<p>Here is a summary.</p>
<p><strong>Bing</strong></p>
<p><em>Task: Search</em></p>
<ul>
<li>1-n GET requests for auto-completing search string.</li>
<li>One POST with XML for fetching search results</li>
<li>A couple of POST requests for instrumentation &#8211; these are like beacon requests with zero length responses.</li>
</ul>
<p><strong>Google</strong></p>
<p><em>Task: Search</em></p>
<ul>
<li>Seven short POST requests exchanging some <code>application/binary</code> content &#8211; not sure what their purpose is</li>
<li>1-n GET requests for auto-completing search string. The response is <code>application/json</code>, but the resposne is actually Javascript (and so the <code>Content-Type</code> should be `application/javascript&#8217;.</li>
<li>Four GET requests to log suggestions. These are again like beacon requests with zero-length responses.</li>
<li>One GET for search results</li>
</ul>
<p><strong>Mint</strong></p>
<p><em>Task: Open the app</em></p>
<ul>
<li>26 requests over TLS &#8211; I suspect that the number of requests depends on the number of accounts &#8211; now I know why this app is so slow on my iPhone.</li>
</ul>
<p><strong>Netflix</strong></p>
<p><em>Task: Open the app</em></p>
<ul>
<li>One request over TLS, probably for some token exchange.</li>
<li>One GET to fetch some config data</li>
<li>One GET to fetch some policy related info</li>
<li>One GET to get date-time from server (why not <code>Date</code> from a previous response?)</li>
<li>One GET to get rental history, two GETs to get rental queue, two POSTs for ratings, one GET for account info, another GET config request, one GET for catalog, and a POST for some misc data</li>
<li>A number of unconditional GET requests for static assets with expires set to a day later</li>
</ul>
<p><strong>Amazon</strong></p>
<p><em>Task: Open the app</em></p>
<p>Just two POST requests with application/octet-stream encoded data.</p>
<p><strong>LinkedIn</strong></p>
<p><em>Task: Open the app</em></p>
<ul>
<li>One GET for the profile</li>
<li>One GET for messages</li>
<li>One GET for some alerts</li>
<li>One GET for favorites</li>
<li>One POST to report metrics</li>
</ul>
<p>The order and number of these requests depends on the UI state of the app.</p>
<p><strong>Facebook</strong> </p>
<p><em>Task: Open the app</em></p>
<ul>
<li>Six pre-flight GET requests &#8211; not sure what the purpose is &#8211; there is not much that I could discern from responses</li>
<li>One request over TLS</li>
<li>A POST multipart/form-data request with an XML response (falsely advertised as text/html) with some profile data</li>
<li>One multipart/form-data POST request &#8211; the response is XML encoded within XML.</li>
<li>A number of unconditional GETs for static assets &#8211; expiry set for a few months</li>
</ul>
<p>Ignoring some funny use of HTTP, my key observation is that most apps are built on top of existing &#8220;APIs&#8221;. The APIs are providing access to different types of data, and the app is aggregating that data from the client (the phone) side. So, even simple actions like opening an app cause a number of requests from the client. All the apps I tested are branded and not built by third-parties and hence do have every chance to optimize the traffic.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.subbu.org/blog/2011/01/chatty-apps/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Slides from the Colorado Software Summit</title>
		<link>http://www.subbu.org/blog/2008/10/slides-from-the-colorado-software-summit</link>
		<comments>http://www.subbu.org/blog/2008/10/slides-from-the-colorado-software-summit#comments</comments>
		<pubDate>Mon, 27 Oct 2008 03:30:05 +0000</pubDate>
		<dc:creator>Subbu Allamaraju</dc:creator>
				<category><![CDATA[REST]]></category>

		<guid isPermaLink="false">http://www.subbu.org/?p=535</guid>
		<description><![CDATA[I spent last week at 9300ft above the sea level at Keystone (CO) attending the Colorado Software Summit. This is one of the best conferences I have attended in a long time, with just about 300 attendees and serious sessions with very little fluff and absolutely no product/vendor pitch of any kind. This is one [...]]]></description>
			<content:encoded><![CDATA[<p></p><div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.subbu.org%2Fblog%2F2008%2F10%2Fslides-from-the-colorado-software-summit"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.subbu.org%2Fblog%2F2008%2F10%2Fslides-from-the-colorado-software-summit&amp;style=normal&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p>I spent last week at 9300ft above the sea level at Keystone (CO) attending the <a href="http://www.coloradosoftwaresummit.com/">Colorado Software Summit</a>. This is one of the best conferences I have attended in a long time, with just about 300 attendees and serious sessions with very little fluff and absolutely no product/vendor pitch of any kind. This is one conference that I can recommend to any one who value their money and time spent on conferences.</p>
<p>Here are the slides for my sessions:</p>
<p><span id="more-535"></span></p>
<p><strong>Pragmatic REST</strong>: This session is about building HTTP APIs RESTfully.</p>
<div style="width:425px;text-align:left" id="__ss_699233"><a style="font:14px Helvetica,Arial,Sans-serif;display:block;margin:12px 0 3px 0;text-decoration:underline;" href="http://www.slideshare.net/sallamar/pragmatic-rest-presentation?type=powerpoint" title="Pragmatic Rest">Pragmatic Rest</a><object style="margin:0px" width="425" height="355"><param name="movie" value="http://static.slideshare.net/swf/ssplayer2.swf?doc=pragmaticrest-1225213907285838-8&#038;stripped_title=pragmatic-rest-presentation" /><param name="allowFullScreen" value="true"/><param name="allowScriptAccess" value="always"/><embed src="http://static.slideshare.net/swf/ssplayer2.swf?doc=pragmaticrest-1225213907285838-8&#038;stripped_title=pragmatic-rest-presentation" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="355"></embed></object>
<div style="font-size:11px;font-family:tahoma,arial;height:26px;padding-top:2px;">View SlideShare <a style="text-decoration:underline;" href="http://www.slideshare.net/sallamar/pragmatic-rest-presentation?type=powerpoint" title="View Pragmatic Rest on SlideShare">presentation</a> or <a style="text-decoration:underline;" href="http://www.slideshare.net/upload?type=powerpoint">Upload</a> your own. (tags: <a style="text-decoration:underline;" href="http://slideshare.net/tag/rest">rest</a>)</div>
</div>
<p>Here is the <a href="http://www.subbu.org/uploads/2008/10/PragmaticREST.pdf">link</a> to download a PDF version.</p>
<p><strong>RESTful Web Apps</strong>: This session is about the RESTful aspects of the web, and how certain mainstream Java web frameworks make it harder to build web apps that play nice with the web architecture. My slides for this session are not as polished as I would have liked, but well &#8211; that&apos;s all the time I have.</p>
<div style="width:425px;text-align:left" id="__ss_699245"><a style="font:14px Helvetica,Arial,Sans-serif;display:block;margin:12px 0 3px 0;text-decoration:underline;" href="http://www.slideshare.net/sallamar/restful-web-apps-facts-vs-fiction-presentation?type=powerpoint" title="RESTful Web Apps - Facts vs Fiction">RESTful Web Apps &#8211; Facts vs Fiction</a><object style="margin:0px" width="425" height="355"><param name="movie" value="http://static.slideshare.net/swf/ssplayer2.swf?doc=restfulwebapps-1225214252037687-8&#038;stripped_title=restful-web-apps-facts-vs-fiction-presentation" /><param name="allowFullScreen" value="true"/><param name="allowScriptAccess" value="always"/><embed src="http://static.slideshare.net/swf/ssplayer2.swf?doc=restfulwebapps-1225214252037687-8&#038;stripped_title=restful-web-apps-facts-vs-fiction-presentation" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="355"></embed></object>
<div style="font-size:11px;font-family:tahoma,arial;height:26px;padding-top:2px;">View SlideShare <a style="text-decoration:underline;" href="http://www.slideshare.net/sallamar/restful-web-apps-facts-vs-fiction-presentation?type=powerpoint" title="View RESTful Web Apps - Facts vs Fiction on SlideShare">presentation</a> or <a style="text-decoration:underline;" href="http://www.slideshare.net/upload?type=powerpoint">Upload</a> your own.</div>
</div>
<p>Here is the <a href="http://www.subbu.org/uploads/2008/10/RESTfulWebApps.pdf">link</a> to download a PDF version.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.subbu.org/blog/2008/10/slides-from-the-colorado-software-summit/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Where Do Resources Come From?</title>
		<link>http://www.subbu.org/blog/2008/10/where-do-resources-come-from</link>
		<comments>http://www.subbu.org/blog/2008/10/where-do-resources-come-from#comments</comments>
		<pubDate>Thu, 23 Oct 2008 02:10:35 +0000</pubDate>
		<dc:creator>Subbu Allamaraju</dc:creator>
				<category><![CDATA[REST]]></category>
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.subbu.org/?p=522</guid>
		<description><![CDATA[Here is the approach I used in my session at the Colorado Software Summit on REST (I will post the slides over the weekend) to find resources. Domain Nouns: This is the most natural approach for finding resources, but it can end up with an inconvenient resource model. For instance, the NYT Movie Reviews API [...]]]></description>
			<content:encoded><![CDATA[<p></p><div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.subbu.org%2Fblog%2F2008%2F10%2Fwhere-do-resources-come-from"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.subbu.org%2Fblog%2F2008%2F10%2Fwhere-do-resources-come-from&amp;style=normal&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p>Here is the approach I used in my session at the <a href="http://coloradosoftwaresummit.org">Colorado Software Summit</a> on REST (I will post the slides over the weekend) to find resources.</p>
<p><span id="more-522"></span></p>
<p><img src="http://www.subbu.org/uploads/2008/10/finding_resources.png" alt="Finding Resources" title="Finding Resources" /></p>
<ul>
<li><strong>Domain Nouns: </strong> This is the most natural approach for finding resources, but it can end up with an inconvenient resource model. For instance, the <a href="http://developer.nytimes.com/docs/movie_reviews_api/">NYT Movie Reviews API</a> has things like Movies, Reviews, Critics, Critic&apos;s picks, Reviews by reviewer identified as resources. These can provide a good starting point, but may not meet the needs of client apps, which leads to the next step.
    </li>
<li><strong>Composites: </strong> These are combinations of other resources, created primarily to address client app needs. Composites can also fix the urge for batching. An example is &quot;a user profile with 5 contacts plus favorite colors plus 10 latest updates&quot; identified as a single resource, so that the client developer can get with a single GET.
    </li>
<li><strong>Tasks and Processes: </strong> An example is an account transfer with some back-end process to complete the transfer at the end of the business day. Some in the audience wondered if it is RESTful to identify such an account transfer &quot;process&quot; (something that is typically identified as a verb). But why not? Such processes can be resources themselves with their own state and lifecycle.
    </li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.subbu.org/blog/2008/10/where-do-resources-come-from/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Explaining State in HATEOAS</title>
		<link>http://www.subbu.org/blog/2008/10/explaining-state-in-hateoas</link>
		<comments>http://www.subbu.org/blog/2008/10/explaining-state-in-hateoas#comments</comments>
		<pubDate>Wed, 22 Oct 2008 15:16:22 +0000</pubDate>
		<dc:creator>Subbu Allamaraju</dc:creator>
				<category><![CDATA[REST]]></category>

		<guid isPermaLink="false">http://www.subbu.org/?p=503</guid>
		<description><![CDATA[Explaining &#34;state&#34; in &#34;Hypermedia as the Engine of Application State&#34; (HATEOAS) is a bit tricky, particularly when you have to do it under two minutes. The problem is that, the word &#34;state&#34; means different things to different people. For most of us coming from some background in web development, state usually involves numbers, strings, booleans, [...]]]></description>
			<content:encoded><![CDATA[<p></p><div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.subbu.org%2Fblog%2F2008%2F10%2Fexplaining-state-in-hateoas"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.subbu.org%2Fblog%2F2008%2F10%2Fexplaining-state-in-hateoas&amp;style=normal&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p>Explaining &quot;state&quot; in &quot;Hypermedia as the Engine of Application State&quot; (HATEOAS) is a bit tricky, particularly when you have to do it under two minutes.</p>
<p>The problem is that, the word &quot;state&quot; means different things to different people. For most of us coming from some background in web development, state usually involves numbers, strings, booleans, and other objects stored in some place, say, in an in-memory session. For instance, every beginner-level book on web development includes a shopping cart style sample that stores the cart in an in-memory session. If we extend that notion to understand or explain HATEOAS, it would make us jump to the conclusion that, to make hypermedia as the engine of application state, the server will have to encode similar objects into some XML or such form of representation in response to each request. This line of thinking is a trap.</p>
<p><span id="more-503"></span></p>
<p>Here is why. Once the server includes such state in a representation, the next step for the client is to replay the state in future requests to the server. Then we are talking about exchanging those objects back and forth, and not every HTTP verb has enough room to carry that state. This line of thinking will then start to shoot holes into the notion of a uniform interface because, to fit the state in a request, the client may have to resort to POST. I can almost see message passing over POST as the next logical step. At this stage, whoever is trying to explain HATEOAS may have make some lame excuses and move on. Whoever is listening will then conclude that &quot;yeah, this won&apos;t work for my apps&quot;. </p>
<p>Here is an example that I find most useful to explain the &quot;state&quot; in HATEOAS.</p>
<blockquote>
<p>There are three pages in a UI. The first page has a link to go to the second page. The second page has a link to go to the previous page as well as the third page. The third has a link to the second page and another link to the first page.</p>
<p>A client starts from the first page, and then through the link on that page, goes to the second page. The fact that this page has one link to the first page and another to the third page implies that the current state of the application (i.e. the interactions) is that &quot;the client is viewing the second page&quot;. That is what it means by hypermedia as the engine of application state. It does not necessarily mean serializing application state, such as &quot;<code>&lt;page&gt;2&lt;/page&gt;</code>&quot; into representations. </p>
</blockquote>
<p>I admit that I am simplifying this a bit. The point is that state does not necessarily mean some data stored in representations. HATEOAS means that representations reflect the current state of the app through <a href="http://www.subbu.org/blog/2008/10/generalized-linking">links</a> with known relations. Those links may contain opaque references to some persistent state on the server.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.subbu.org/blog/2008/10/explaining-state-in-hateoas/feed</wfw:commentRss>
		<slash:comments>13</slash:comments>
		</item>
		<item>
		<title>application/xxx+json</title>
		<link>http://www.subbu.org/blog/2008/10/applicationxxxjson</link>
		<comments>http://www.subbu.org/blog/2008/10/applicationxxxjson#comments</comments>
		<pubDate>Thu, 09 Oct 2008 22:57:59 +0000</pubDate>
		<dc:creator>Subbu Allamaraju</dc:creator>
				<category><![CDATA[REST]]></category>
		<category><![CDATA[JSON]]></category>
		<category><![CDATA[WADL]]></category>

		<guid isPermaLink="false">http://www.subbu.org/?p=453</guid>
		<description><![CDATA[Why did RFC-4267 not leave room for a JSON-family of representations? For XML, RFC 3023 formally defined XML-based media types using the &#34;+xml&#34; naming convention, so that clients (e.g. XMLHttpRequest) can recognize any XMLish media type as long as the media type follows this convention. But not so for JSON?]]></description>
			<content:encoded><![CDATA[<p></p><div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.subbu.org%2Fblog%2F2008%2F10%2Fapplicationxxxjson"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.subbu.org%2Fblog%2F2008%2F10%2Fapplicationxxxjson&amp;style=normal&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p>Why did <a href="http://www.ietf.org/rfc/rfc4627.txt">RFC-4267</a> not leave room for a JSON-family of representations?  For XML, <a href="http://www.ietf.org/rfc/rfc3023.txt">RFC 3023</a> formally defined <em>XML-based media types</em> using the &quot;+xml&quot; naming convention, so that clients (e.g. <a href="http://www.w3.org/TR/XMLHttpRequest/">XMLHttpRequest</a>) can recognize any XMLish media type as long as the media type follows this convention. But not so for JSON?</p>
]]></content:encoded>
			<wfw:commentRss>http://www.subbu.org/blog/2008/10/applicationxxxjson/feed</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>On Partial Representations</title>
		<link>http://www.subbu.org/blog/2008/09/on-partial-representations</link>
		<comments>http://www.subbu.org/blog/2008/09/on-partial-representations#comments</comments>
		<pubDate>Mon, 22 Sep 2008 01:41:17 +0000</pubDate>
		<dc:creator>Subbu Allamaraju</dc:creator>
				<category><![CDATA[HTTP]]></category>
		<category><![CDATA[REST]]></category>

		<guid isPermaLink="false">http://www.subbu.org/?p=296</guid>
		<description><![CDATA[A partial representation is one where the client would ask for a specific bits and pieces of a representation, such as Amazon serving a partial representation of a book containing just the table of contents, or just the reviews and comments. The problem is quite simple, and a  solution like the following would work: GET [...]]]></description>
			<content:encoded><![CDATA[<p></p><div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.subbu.org%2Fblog%2F2008%2F09%2Fon-partial-representations"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.subbu.org%2Fblog%2F2008%2F09%2Fon-partial-representations&amp;style=normal&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p>A partial representation is one where the client would ask for a specific bits and pieces of a representation, such as Amazon serving a partial representation of a book containing just the table of contents, or just the reviews and comments. The problem is quite simple, and a  solution like the following would work:</p>
<pre name="code" class="http">
GET /book/0-374-29288-4?view=toc
GET /book/0-374-29288-4?view=reviews
GET /book/0-374-29288-4?fields=reviews,comments
</pre>
<p><span id="more-296"></span></p>
<p>At Yahoo!, we call this the &quot;view&quot; pattern. The key thing to note here is that the names of views or fields don&apos;t necessarily refer to particular members of representations &#8211; such as elements/attributes in XML-family of representations or properties in JSON representations. It is up to the server to define what the values of those parameters mean. They could potentially mean inclusion/exclusion of different members of representations in particular media types. This way, we can let URIs remain decoupled from particular media types. I consider this important to let the system evolve to support conneg for what it is designed for.</p>
<p>Flickr solves the same use case by taking an <code>extras</code> query parameter with a list of fields to include for its <a href="http://www.flickr.com/services/api/flickr.photos.search.html">search</a> API.</p>
<p>Another reason we adopted this pattern for serving partial representations is that this approach lets us link to those representations, as in</p>
<pre name="code" class="xml">
&lt;link href="/book/0-374-29288-4?view=toc" rel="view"/&gt;
&lt;link href="/book/0-374-29288-4?view=reviews" rel="view"/&gt;
&lt;link href="/book/0-374-29288-4?fields=reviews,comments" rel="view"/&gt;
</pre>
<p>By being able to link like this, we can take advantage of HATEOAS as well as do some interesting things that only opaque URIs let us do.</p>
<p>Although this approach is quite common, once in a while we come across some proposals that deserve a bit more scrutiny.</p>
<p>The most recent approaches that I came across with are from the <a href="http://groups.google.com/group/restful-json/msg/94834c62b0fbd90a?">RESTful JSON</a> proposal. The first is based on a new &quot;<code>locator</code>&quot; media type parameter. In this model, a client would include a header such as</p>
<pre name="code" class="http">
Content-Type: application/json;locator=my_id[{"my_id":"1","name":"John Doe"},{"my_id":"2","name":"Jane Doe"}]
</pre>
<p>The idea of this locator is to identify a sub-resource. This is an interesting but questionable usage of the Content-Type header. I say questionable because the purpose of the <code>Content-Type</code> header is to indicate the media type of the entity enclosed in the body of a request or a response. Here, what is included is not just a media type of the entity. It is also encoding data, thus mixing up resource naming and resource data. In RESTful systems, we use URIs to name resources, and let headers provide metadata of a request/response or the entity enclosed within a request/response.</p>
<p>The same proposal includes another idea to deal with partial representations of collections of resources. That is to rely on the <code>Range</code> and <code>Content-Range</code> headers. Here is an example.</p>
<pre name="code" class="http">
GET /Person/ HTTP/1.1
Range: items=0-1

Content-Range: items 0-1/33

...
</pre>
<p>Here, the client is asking for the first two elements of a collection using the <code>Range</code> header.</p>
<p>In HTTP, Both <code>Content-Range</code> and <code>Range</code> headers describe byte ranges. See Sec 3.12 of RFC 2616, which recognizes &quot;bytes&quot; as the unit of content range. RFC 2616 does allow extensions, but software that can recognize byte ranges is likely going to trip when it sees extensions like this.</p>
<p>Most importantly, both these approaches prevent linking. You can&apos;t claim a solution to be RESTful if you can&#8217;t use it to link to a resource or a representation.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.subbu.org/blog/2008/09/on-partial-representations/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
	</channel>
</rss>

