<?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>Ben Longden</title>
	<atom:link href="http://nocarrier.co.uk/feed/" rel="self" type="application/rss+xml" />
	<link>http://nocarrier.co.uk</link>
	<description>PHP, Hypermedia and some other bits...</description>
	<lastBuildDate>Thu, 07 Mar 2013 19:39:04 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.5.1</generator>
		<item>
		<title>Expanding Zoom</title>
		<link>http://nocarrier.co.uk/2013/03/expanding-zoom/</link>
		<comments>http://nocarrier.co.uk/2013/03/expanding-zoom/#comments</comments>
		<pubDate>Wed, 06 Mar 2013 11:14:26 +0000</pubDate>
		<dc:creator>blongden</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://nocarrier.co.uk/?p=232</guid>
		<description><![CDATA[There&#8217;s been some recent discussion on the hal-discuss mailing list around the &#8216;Zoom&#8217; concept for embedding resources, which has prompted me to start exploring this area a little further with a view to potentially writing up a specification that can be applied to any media type that define a way of embedding resources. This blog [...]]]></description>
				<content:encoded><![CDATA[<p>There&#8217;s been some recent discussion on the hal-discuss mailing list around the &#8216;Zoom&#8217; concept for embedding resources, which has prompted me to start exploring this area a little further with a view to potentially writing up a specification that can be applied to any media type that define a way of embedding resources. This blog post mostly serves as a narrative to document my own ideas and learnings and to collect comments and recommendations from others in order to arrive at a proposal that will work for (almost!) everyone.</p>
<p>At its most simple level, clients need a way of being able to take an existing resource with defined link relations and zoom (or expand) the current resource to include them in the response. This is primarily to avoid a second round trip to the server in order to retrieve the resource representation that the client is interested in seeing.</p>
<p>To illustrate the problem, I have provided an example (for the sake of brevity, I have only included relevant parts of the resource representation).</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #009900;">&#123;</span>
    <span style="color: #3366CC;">&quot;_links&quot;</span><span style="color: #339933;">:</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #3366CC;">&quot;http://.../rels/detail&quot;</span><span style="color: #339933;">:</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #3366CC;">&quot;href&quot;</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;/example/1/detail&quot;</span>
        <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
        <span style="color: #3366CC;">&quot;http://.../rels/misc&quot;</span><span style="color: #339933;">:</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #3366CC;">&quot;href&quot;</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;/example/1/misc&quot;</span>
        <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
        <span style="color: #3366CC;">&quot;self&quot;</span><span style="color: #339933;">:</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #3366CC;">&quot;href&quot;</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;/example/1&quot;</span>
        <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>In the above example, imagine a scenario where the client that has requested this representation is actually interested in the resource found at the &#8216;http://&#8230;/rels/detail&#8217; link relation. The client now has to make a second request to the server in order to get at the data it needs.</p>
<p>We can alleviate this by using a feature of the media type known as embedding &#8211; however it is impractical to embed every linked resource every time. We must provide a way of allowing the client to specify the resource it is interested in &#8211; and this is &#8216;Zoom&#8217;.</p>
<p>If we allow the &#8216;zoom&#8217; (or &#8216;z&#8217;) parameter in the query string to be reserved for this purpose, we can request that the server embeds the link relation by performing a GET request on &#8216;http://&#8230;/example/1?zoom=http://&#8230;/rels/detail&#8217;. The server would then be given the instruction to embed the resource and return it all in the response.</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #009900;">&#123;</span>
    <span style="color: #3366CC;">&quot;_embedded&quot;</span><span style="color: #339933;">:</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #3366CC;">&quot;http://.../rels/detail&quot;</span><span style="color: #339933;">:</span> <span style="color: #009900;">&#91;</span>
            <span style="color: #009900;">&#123;</span>
                <span style="color: #3366CC;">&quot;_links&quot;</span><span style="color: #339933;">:</span> <span style="color: #009900;">&#123;</span>
                    <span style="color: #3366CC;">&quot;self&quot;</span><span style="color: #339933;">:</span> <span style="color: #009900;">&#123;</span>
                        <span style="color: #3366CC;">&quot;href&quot;</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;/example/1/detail&quot;</span>
                    <span style="color: #009900;">&#125;</span>
                <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
                <span style="color: #3366CC;">&quot;firstname&quot;</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;Ben&quot;</span><span style="color: #339933;">,</span>
                <span style="color: #3366CC;">&quot;lastname&quot;</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;Longden&quot;</span>
            <span style="color: #009900;">&#125;</span>
        <span style="color: #009900;">&#93;</span>
    <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
    <span style="color: #3366CC;">&quot;_links&quot;</span><span style="color: #339933;">:</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #3366CC;">&quot;http://.../rels/detail&quot;</span><span style="color: #339933;">:</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #3366CC;">&quot;href&quot;</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;/example/1/detail&quot;</span>
        <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
        <span style="color: #3366CC;">&quot;http://.../rels/misc&quot;</span><span style="color: #339933;">:</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #3366CC;">&quot;href&quot;</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;/example/1/misc&quot;</span>
        <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
        <span style="color: #3366CC;">&quot;self&quot;</span><span style="color: #339933;">:</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #3366CC;">&quot;href&quot;</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;/example/1&quot;</span>
        <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>If we wanted to embed two items, the zoom query parameter may accept multiple link relations separated by commas, i.e., http://&#8230;/example/1?zoom=http://&#8230;/rels/detail,http://&#8230;/rels/misc.</p>
<p>The HAL format also supports CURIE style links to shorten the length of link relations and abbreviate the link down to a &#8216;x:detail&#8217; or &#8216;x:misc&#8217; format. There is no reason to not support these shorter syntax link rels, if the CURIE can be resolved. Here is an example of &#8216;http://&#8230;/example/1/?zoom=x:detail&#8217;.</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #009900;">&#123;</span>
    <span style="color: #3366CC;">&quot;_embedded&quot;</span><span style="color: #339933;">:</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #3366CC;">&quot;x:detail&quot;</span><span style="color: #339933;">:</span> <span style="color: #009900;">&#91;</span>
            <span style="color: #009900;">&#123;</span>
                <span style="color: #3366CC;">&quot;_links&quot;</span><span style="color: #339933;">:</span> <span style="color: #009900;">&#123;</span>
                    <span style="color: #3366CC;">&quot;self&quot;</span><span style="color: #339933;">:</span> <span style="color: #009900;">&#123;</span>
                        <span style="color: #3366CC;">&quot;href&quot;</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;/example/1/detail&quot;</span>
                    <span style="color: #009900;">&#125;</span>
                <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
                <span style="color: #3366CC;">&quot;firstname&quot;</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;Ben&quot;</span><span style="color: #339933;">,</span>
                <span style="color: #3366CC;">&quot;lastname&quot;</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;Longden&quot;</span>
            <span style="color: #009900;">&#125;</span>
        <span style="color: #009900;">&#93;</span>
    <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
    <span style="color: #3366CC;">&quot;_links&quot;</span><span style="color: #339933;">:</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #3366CC;">&quot;curies&quot;</span><span style="color: #339933;">:</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #3366CC;">&quot;href&quot;</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;http://.../rels/{rel}&quot;</span><span style="color: #339933;">,</span>
            <span style="color: #3366CC;">&quot;name&quot;</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;x&quot;</span><span style="color: #339933;">,</span>
            <span style="color: #3366CC;">&quot;templated&quot;</span><span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">true</span>
        <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
        <span style="color: #3366CC;">&quot;self&quot;</span><span style="color: #339933;">:</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #3366CC;">&quot;href&quot;</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;/example/1&quot;</span>
        <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
        <span style="color: #3366CC;">&quot;x:detail&quot;</span><span style="color: #339933;">:</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #3366CC;">&quot;href&quot;</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;/example/1/detail&quot;</span>
        <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
        <span style="color: #3366CC;">&quot;x:misc&quot;</span><span style="color: #339933;">:</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #3366CC;">&quot;href&quot;</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;/example/1/misc&quot;</span>
        <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>The above examples and narrative cover zoom at it&#8217;s most basic implementation &#8211; and this will fit many situations fairly well. However, this idea of partially embedding sub resources is not new &#8211; what we are seeking is a unified way of following this pattern so that a common approach can be applied to any media type that has the ability to embed resources.</p>
<p>Implementations of this pattern can be found &#8216;in the wild&#8217; in a number of places &#8211; to varying levels of completeness. From simply being able to embed a resource in a representation through to being able to specify a DSL to allow clients to query data that&#8217;s returned (specifying a limit to the number of resources in an embedded collection, or filtering by values in an embedded collection.</p>
<p>I&#8217;ll write up some thoughts around querying and limiting embedded data in a future post &#8211; i&#8217;d like to keep things relatively simple for now, and dive deeper into what the possibilities are later!</p>
<p>Comments more than welcome below.</p>
]]></content:encoded>
			<wfw:commentRss>http://nocarrier.co.uk/2013/03/expanding-zoom/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Hypermedia types and connection negotiation</title>
		<link>http://nocarrier.co.uk/2012/09/hypermedia-types-and-connection-negotiation/</link>
		<comments>http://nocarrier.co.uk/2012/09/hypermedia-types-and-connection-negotiation/#comments</comments>
		<pubDate>Tue, 25 Sep 2012 09:21:33 +0000</pubDate>
		<dc:creator>blongden</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[hypermedia]]></category>
		<category><![CDATA[rest]]></category>

		<guid isPermaLink="false">http://nocarrier.co.uk/?p=216</guid>
		<description><![CDATA[I was fortunate enough to be able to travel to RESTFest in Greenville SC over the past week to spend time mixing with people who are highly influential in the world of REST and Hypermedia. Many interesting things where discussed there and it got me thinking about connection negotiation a little more (one of many [...]]]></description>
				<content:encoded><![CDATA[<p>I was fortunate enough to be able to travel to RESTFest in Greenville SC over the past week to spend time mixing with people who are highly influential in the world of REST and Hypermedia. Many interesting things where discussed there and it got me thinking about connection negotiation a little more (one of many many things I have taken away from the conference &#8211; subjects for later articles!)</p>
<p>Before attending the conference I had always advocated taking an existing hypermedia type (for the examples here I will use application/hal+json) and trying to represent a resource using that. More often than not, I would require some affordances that are not defined in the spec &#8211; so extending it and creating my own vender specific mime type (which defines what base type it extends) made a lot of sense to me.</p>
<p>Now that various media types are become ubiquitous amongst API designers (Hal and collection+json amongst others), it&#8217;s made me see the advantage of sticking to the base type whilst negotiating with the server on what content you receive. The reason? Because other clients that understand these hypermedia types are staring to emerge &#8211; much like the web browsers in which we browse the text/html hypermedia type today.</p>
<p>Like HTML, hypermedia types are created with the understanding that if an element exists that the client is not able to assign meaning to (an affordance that is not part of the spec, or not implemented by the client), then it can simply ignore it as if it was never there. This is quite powerful &#8211; it allows you to define optional extensions to a hypermedia type whilst maintaining compatibility with clients and intermediaries which already understand your base type.</p>
<p>Collection+json supports this idea quite well, and the author (Mike Amundsen) accepts additional patches to define extensions as part of the specification &#8211; extensions that one day could form part of a revised version of the specification for everyone to use, but exist as extensions that can be understood by any third party client that support them.</p>
<p>It is now my opinion that the creation of custom mime types (without registering them with IANA) actually harm the interoperability of the web &#8211; and close down a hypermedia API to clients which have specifically been created for your own hypermedia type.</p>
<p>Perhaps a missing piece of the puzzle right now is a way of being able to declare which extensions your document is actually making use of (if this is even needed once the extensions become part of the specification). Using a Link header (http://www.w3.org/wiki/LinkHeader) is potentially a good way of achieving this, though exactly how this works in practice is still being considered.</p>
<p>Comments encouraged!</p>
]]></content:encoded>
			<wfw:commentRss>http://nocarrier.co.uk/2012/09/hypermedia-types-and-connection-negotiation/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Writing RESTful clients</title>
		<link>http://nocarrier.co.uk/2012/07/writing-restful-clients/</link>
		<comments>http://nocarrier.co.uk/2012/07/writing-restful-clients/#comments</comments>
		<pubDate>Wed, 18 Jul 2012 16:37:06 +0000</pubDate>
		<dc:creator>blongden</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[development]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[rest]]></category>

		<guid isPermaLink="false">http://nocarrier.co.uk/?p=206</guid>
		<description><![CDATA[There&#8217;s plenty of articles out there on how to build the perfect REST API, so I am not going to go into that. This article is all about what to think about when you&#8217;re building the perfect client for a REST API. What you&#8217;re being served is clearly important &#8211; but how you use that [...]]]></description>
				<content:encoded><![CDATA[<p>There&#8217;s plenty of articles out there on how to build the perfect REST API, so I am not going to go into that. This article is all about what to think about when you&#8217;re building the perfect client for a REST API. What you&#8217;re being served is clearly important &#8211; but how you use that information is 50% of the problem &#8211; and it needs to be done correctly.</p>
<p>API designers can spend a lot of time ensuring that their responses to you are perfectly well formed and self describing &#8211; but unless you pay attention to what it is that those messages are telling you, all that information is simply being thrown away.</p>
<h1 id="connection-negotiation">Connection Negotiation</h1>
<p>The very first thing your HTTP client will send to the server is the Request headers. Within that request, more often than not, you will send the Accept header and a list of media types that your client can support &#8211; and the order of preference within which you would like to see them. Chrome 20.0.1132.47 sends the following Accept header.</p>
<p>Accept:text/html,application/xhtml+xml,application/xml;q=0.9,<em>/</em>;q=0.8</p>
<p>Obviously this is a web browser, so it&#8217;s preference is going to be for text/html or application/xhtml+xml. Failing that, we can also take application/xml. If the server still can&#8217;t handle the request &#8211; then we&#8217;ll take anything at all (*/*).</p>
<p>The web server will make a decision based on what your client has asked for. From that point on one of 3 things can happen. 1) You get back one of the media formats that you asked for. 2) You receive a 406 response (Not Acceptable). 3) You get back something you didn&#8217;t ask for at all (this is allowed as per RFC2616 &#8211; the server SHOULD only respond with a 406).</p>
<p>This means that unless you&#8217;re explicitly checking what the response is after the request comes back &#8211; you could find yourself only assuming that the server is behaving as you think it is.</p>
<p>The Accept header becomes very useful when you separate out a normal response from an error response. In the situation where a server error is causing a problem, you are likely to receive a 5xx response code from the server with little or no meaningful body (text/plain). Where an application error has occured you should also receive a 5xx (or a 4xx) code from the server &#8211; however having declared you are able to handle a more specific media type (application/vnd.error+xml for example), you are able to present more information to the user than you would otherwise be able to.</p>
<p>Take the situation where you are consuming an API which serves up application/hal+xml and text/plain (hal for the resource representation, and a plain text for an error). The server is free to be able to add support for representing errors in application/vnd.error+xml without affecting any existing client &#8211; as long as the server continues to serve text/plain unless the new media type is deemed as acceptable to the client. Once the client is updated to add support for the new media type, it can take advantage of the additional information that can be provided.</p>
<h1 id="cache">Cache</h1>
<p>A RESTful API will contain explicit directives that declare if and for how long the response body can be cached for. This information is contained across Cache-Control / Vary headers or Expires header. If the response to your request comes back from the server and declared itself as being able to be cached (only Cache-Control: no-store is excluded from user-agent caches) then you should store it locally and serve up the cached response as long as it&#8217;s valid.</p>
<p>There are of course already libraries you can use in your projects that will handle cacheing for you. If you usually use PHP for this stuff (I do), then I highly recommend you take a look at <a href="http://guzzlephp.org/">Guzzle</a> to handle this for you.</p>
<h1 id="urls">URLs</h1>
<p>Yeah i&#8217;m going to talk about it again. Hypertext as the engine of application state. Golden rule #1, never construct links in code (unless you&#8217;re following a <a href="http://tools.ietf.org/html/rfc6570">URI Template</a>) &#8211; follow them from the links given to you in the resource. This means that when these links change &#8211; you don&#8217;t have to worry about your app breaking. #2, use the defined link relations of the hypermedia type to navigate through the application (ie, HTML&#8217;s &#8216;rel&#8217; attribute on the link tag). That&#8217;s about it. Don&#8217;t assume anything if it&#8217;s not defined by the media type rules and the representation you receive and you can&#8217;t go wrong.</p>
]]></content:encoded>
			<wfw:commentRss>http://nocarrier.co.uk/2012/07/writing-restful-clients/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>JSON Sucks</title>
		<link>http://nocarrier.co.uk/2012/04/json-sucks/</link>
		<comments>http://nocarrier.co.uk/2012/04/json-sucks/#comments</comments>
		<pubDate>Thu, 26 Apr 2012 22:02:10 +0000</pubDate>
		<dc:creator>blongden</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[hypermedia]]></category>
		<category><![CDATA[json]]></category>
		<category><![CDATA[xml]]></category>

		<guid isPermaLink="false">http://nocarrier.co.uk/?p=159</guid>
		<description><![CDATA[Ok, so perhaps I was a little bit OTT with the title of this blog post (but it got your attention, right?). What I actually mean is that JSON Sucks for hypermedia APIs, and I am going to tell you why. But before I do, I just want to point out that actually I think [...]]]></description>
				<content:encoded><![CDATA[<p>Ok, so perhaps I was a little bit OTT with the title of this blog post (but it got your attention, right?). What I actually mean is that JSON Sucks for hypermedia APIs, and I am going to tell you why. But before I do, I just want to point out that actually I think JSON is awesome <strong>for what it&#8217;s designed for</strong> &#8211; serialising an object. Objects naturally contain data structures like ints, strings, arrays and other objects &#8211; if all you need to do is represent those four things, you can&#8217;t go wrong with JSON. Seriously.</p>
<p>Hating XML is rather fashionable these days, so many API&#8217;s are appearing that are JSON representation only even when XML really is a better fit for purpose. When you&#8217;re designing a hypermedia API you&#8217;re not simply serialising an object. There are media types that add semantic meaning to JSON (<a href="http://stateless.co/hal_specification.html">application/hal+json</a>, my own <a href="http://github.com/blongden/vnd.error">application/vnd.error+json (draft)</a> and others) but really, XML is so much more expressive that using JSON actually makes your clients have to work harder to understand the meaning you&#8217;re trying to convey using an object serialisation format over a markup language.</p>
<p>XML gives you some stuff for free &#8211; &#8216;xml:lang&#8217; for one. Put this on any element of your document and just the fact that your document is XML means that you can express elements in different (human) languages without having to update your media type.</p>
<p>Consider how this actually looks in XML vs JSON representation.</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;error</span> <span style="color: #000066;">id</span>=<span style="color: #ff0000;">&quot;6&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;message<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>Something bad happened<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/message<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/error<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></td></tr></table></div>


<div class="wp_syntax"><table><tr><td class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #009900;">&#123;</span>
    <span style="color: #3366CC;">&quot;error&quot;</span><span style="color: #339933;">:</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #3366CC;">&quot;id&quot;</span><span style="color: #339933;">:</span> <span style="color: #CC0000;">6</span><span style="color: #339933;">,</span>
        <span style="color: #3366CC;">&quot;message&quot;</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;Something bad happened&quot;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>This looks easy, right? Consider a future version of the api where we add support for multiple languages.</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;error</span> <span style="color: #000066;">id</span>=<span style="color: #ff0000;">&quot;6&quot;</span> <span style="color: #000066;">xml:lang</span>=<span style="color: #ff0000;">&quot;en&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;message<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>Something bad happened<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/message<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;message</span> <span style="color: #000066;">xml:lang</span>=<span style="color: #ff0000;">&quot;de&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>Etwas schlimmes ist passiert<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/message<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/error<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></td></tr></table></div>


<div class="wp_syntax"><table><tr><td class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #009900;">&#123;</span>
    <span style="color: #3366CC;">&quot;id&quot;</span><span style="color: #339933;">:</span> <span style="color: #CC0000;">6</span><span style="color: #339933;">,</span>
    <span style="color: #3366CC;">&quot;messages&quot;</span><span style="color: #339933;">:</span> <span style="color: #009900;">&#91;</span>
        <span style="color: #009900;">&#123;</span> <span style="color: #3366CC;">&quot;lang&quot;</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;en&quot;</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">&quot;message&quot;</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;Something bad happened&quot;</span> <span style="color: #009900;">&#125;</span>
        <span style="color: #009900;">&#123;</span> <span style="color: #3366CC;">&quot;lang&quot;</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;de&quot;</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">&quot;message&quot;</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;Etwas schlimmes ist passiert&quot;</span> <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#93;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>An alternative could be to key the message objects by language;</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #009900;">&#123;</span>
    <span style="color: #3366CC;">&quot;id&quot;</span><span style="color: #339933;">:</span> <span style="color: #CC0000;">6</span><span style="color: #339933;">,</span>
    <span style="color: #3366CC;">&quot;messages&quot;</span><span style="color: #339933;">:</span> <span style="color: #009900;">&#123;</span> 
        <span style="color: #3366CC;">&quot;en&quot;</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;Something bad happened&quot;</span><span style="color: #339933;">,</span>
        <span style="color: #3366CC;">&quot;de&quot;</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;Etwas schlimmes ist passiert&quot;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>You can see in both scenarios that &#8220;messages&#8221; has become an different type (string to array of objects, or string to object). We&#8217;ve changed the structure of the document and introduced an almost certain backwards compatibility (BC) break in our interface &#8211; all our clients now need to be updates to follow suit. We <strong>could</strong> leave &#8220;message&#8221; as it was, and add &#8220;messages&#8221; for the multilang version of the API but then we&#8217;re duplicating data and / or making the client have to work harder.</p>
<p>The XML version can continue as is and the client can simply ignore the additional languages until they&#8217;re updated to support them (if they ever need to).</p>
<p>Then there&#8217;s just the matter of basic human readability. It&#8217;s clear to see what&#8217;s going on in XML and not so much in JSON. This is a fairly simplistic example but extrapolate that out over a fairly complex representation of an object and you can see how JSON really isn&#8217;t always the best choice for representing resources.</p>
<p>Imagine the scenario where we had used the second option above as our JSON representation and we wanted to add in another attribute for each of the messages. See the problem? Anything we choose to do will cause a BC break and require clients to update (or result in duplication of elements to &#8216;version&#8217; the api), meaning it&#8217;s very difficult to evolve the clients and servers independently.</p>
<p>So i&#8217;m not saying that JSON simply &#8216;sucks&#8217;. I&#8217;m just saying that when considering the formats you use for representing data in an API (when it comes to selecting the media type you want to use), think hard before just going with something based on JSON by default because it&#8217;s &#8216;easy&#8217;. It probably isn&#8217;t.</p>
]]></content:encoded>
			<wfw:commentRss>http://nocarrier.co.uk/2012/04/json-sucks/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>The error hypermedia type</title>
		<link>http://nocarrier.co.uk/2012/04/the-error-hypermedia-type/</link>
		<comments>http://nocarrier.co.uk/2012/04/the-error-hypermedia-type/#comments</comments>
		<pubDate>Tue, 24 Apr 2012 19:17:34 +0000</pubDate>
		<dc:creator>blongden</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[hypermedia]]></category>
		<category><![CDATA[json]]></category>
		<category><![CDATA[xml]]></category>

		<guid isPermaLink="false">http://nocarrier.co.uk/?p=156</guid>
		<description><![CDATA[When designing a complex hypermedia API you will inevitably come across the situation where instead of returning the required resource, you need to return an error state. Currently, there is no hypermedia type registered with IANA to deal with this scenario, so it is left up to the API designer to construct and document a [...]]]></description>
				<content:encoded><![CDATA[<p>When designing a complex hypermedia API you will inevitably come across the situation where instead of returning the required resource, you need to return an error state. Currently, there is no hypermedia type registered with IANA to deal with this scenario, so it is left up to the API designer to construct and document a mime type that can be used to express an error state in the application.</p>
<p>Because of this, several people have come together and put together a proposal for the application/vnd.error media type. It has been documented over on <a href="http://github.com/blongden/vnd.error">Github</a> and the mime type has been submitted for approval by IANA.</p>
<p>The intention for this media type is that it should be used when a client has made a request, however the server is unable to fulfil the request to to either a server side error (a code 5xx) or a problem with the client request (a code 4xx).</p>
<p>Although the client does NOT have to state that it explicitly will accept the application/vnd.error+xml or json mime type (via the &#8216;Accept&#8217; header in the request), it makes a lot of sense to do so if the client can understand that response type. However, <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html">RFC2616 section 10</a> states:</p>
<blockquote>
<p>HTTP/1.1 servers are allowed to return responses which are not acceptable according to the accept headers sent in the request. In some cases, this may even be preferable to sending a 406 response. User agents are encouraged to inspect the headers of an incoming response to determine if it is acceptable.</p>
</blockquote>
<p>It is up to the implementor to decide whether the api should return a 406 (Not Acceptable) response if the client states it will not accept application/vnd.error+xml or json and an error is triggere, or if it should return the application/vnd.error+xml or json response anyway.</p>
<p>The specification for application/vnd.error is draft &#8211; if you have comments / suggestions or enhancements to the media type, let&#8217;s talk (comments on this blog, issues on github, twitter etc).</p>
]]></content:encoded>
			<wfw:commentRss>http://nocarrier.co.uk/2012/04/the-error-hypermedia-type/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>PHP 5.4 web server</title>
		<link>http://nocarrier.co.uk/2012/04/php5-web-server/</link>
		<comments>http://nocarrier.co.uk/2012/04/php5-web-server/#comments</comments>
		<pubDate>Wed, 11 Apr 2012 09:11:53 +0000</pubDate>
		<dc:creator>blongden</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://nocarrier.co.uk/?p=130</guid>
		<description><![CDATA[For me, one of the most exciting things that we have in PHP 5.4 is its built in web server. It makes being able to jump in the deep end with new ideas much easier and avoids the tedious work in setting up and needing apache to run before you have code to deploy. I [...]]]></description>
				<content:encoded><![CDATA[<p>For me, one of the most exciting things that we have in PHP 5.4 is its built in web server. It makes being able to jump in the deep end with new ideas much easier and avoids the tedious work in setting up and needing apache to run before you have code to deploy. I have been playing around with the Silex framework in the last few weeks to build a prototype of a REST API that I have been thinking about. This is how I got going with Silex once I had PHP 5.4 installed.</p>
<p><code><br />
wget http://silex.sensiolabs.org/get/silex.phar<br />
php -S localhost:8080<br />
</code> </p>
<p>Create an index.php in the current directory (there&#8217;s an example app on the Silex home page). That&#8217;s it. Go play. :)</p>
]]></content:encoded>
			<wfw:commentRss>http://nocarrier.co.uk/2012/04/php5-web-server/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Code review Karma</title>
		<link>http://nocarrier.co.uk/2012/04/code-review-karma/</link>
		<comments>http://nocarrier.co.uk/2012/04/code-review-karma/#comments</comments>
		<pubDate>Mon, 09 Apr 2012 12:29:42 +0000</pubDate>
		<dc:creator>blongden</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[development]]></category>

		<guid isPermaLink="false">http://nocarrier.co.uk/?p=125</guid>
		<description><![CDATA[Implementing a good code review system into a development process is something that I have found quite difficult to do. The idea of it is conceptually quite simple &#8211; just make sure that before code is accepted into the main development stream that it&#8217;s reviewed by someone before being allowed to pass. Tools like github [...]]]></description>
				<content:encoded><![CDATA[<p>Implementing a good code review system into a development process is something that I have found quite difficult to do. The idea of it is conceptually quite simple &#8211; just make sure that before code is accepted into the main development stream that it&#8217;s reviewed by someone before being allowed to pass. Tools like github compliment git really well but force you down a development path that really suits open source software development, but not necessarily a co-located team.</p>
<p>My problem is that I trust my developers to do the right thing. Ok, so that&#8217;s not a problem &#8211; it&#8217;s actually a really nice place to be. I see code review as a learning exercise for good developers, but I don&#8217;t see is as a blocking part of the development cycle. Too many times I have seen code reviews as a blocking step in a software release cycle end up just being a formality to get through.</p>
<p>With that scene set i&#8217;ve been thinking of using a karma based code review system. Developers have karma (per project) and can give out positive and negative karma to other developers. At a certain level of karma, the number of reviews required on commits starts to drop off so that eventually a commit by a developer with high karma will not generate a code review (or the percentage of commits submitted for review will be very low). As a project progresses, hopefully this leads to a place where developers who will learn more from having reviews done will have the benefit, while the developers who are well established on the project are able to get code into the project repository without a blocking code review process. Improvement can be measured by karma increasing over time.</p>
<p>Do you have experience with code reviews on projects? (open source vs closed source / colo teams vs non-colo / blocking vs non blocking)&#8230; Interested to hear others success and failure stories!</p>
]]></content:encoded>
			<wfw:commentRss>http://nocarrier.co.uk/2012/04/code-review-karma/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>So you think TDD isn&#8217;t worth the cost?</title>
		<link>http://nocarrier.co.uk/2012/01/so-you-think-tdd-isnt-worth-the-cost/</link>
		<comments>http://nocarrier.co.uk/2012/01/so-you-think-tdd-isnt-worth-the-cost/#comments</comments>
		<pubDate>Sat, 28 Jan 2012 11:16:57 +0000</pubDate>
		<dc:creator>blongden</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[development]]></category>
		<category><![CDATA[tdd]]></category>

		<guid isPermaLink="false">http://nocarrier.co.uk/?p=118</guid>
		<description><![CDATA[Think of the full software development life cycle. We gather requirements, create user stories, break them down into tasks, estimate, fight with your client about how long it&#8217;s all going to take, renegotiate the timings (what&#8217;s 35% of the development time on unit tests? Do we need those?), submit a revised timescale with cut down [...]]]></description>
				<content:encoded><![CDATA[<p>Think of the full software development life cycle. We gather requirements, create user stories, break them down into tasks, estimate, fight with your client about how long it&#8217;s all going to take, renegotiate the timings (what&#8217;s 35% of the development time on unit tests? Do we need those?), submit a revised timescale with cut down requirements and no time allocated to testing. Then we start development.</p>
<p>And soon the problems start coming up. At the end of the first sprint the client raises a few bugs with the software delivery&#8230; We didn&#8217;t account for those in the plan! And we can&#8217;t estimate them &#8211; we don&#8217;t know the size of the problem. That&#8217;s why it&#8217;s a bug&#8230; So we allocate some time in the next sprint to work on the top priority bugs and commit to developing fewer features.</p>
<p>The second sprint finishes, and more defects are raised in the software &#8211; some of them can be attributed to requirements not been defined clearly enough, but some of them are just code that we don&#8217;t understand how it even worked in development! Did someone actually test it before it went into the main development branch?! (how many people can honestly say they have never heard that one before&#8230;?)</p>
<p>Pretty soon you&#8217;re way behind the plan. The number of bugs that we cannot estimate and didn&#8217;t plan for are sucking up too much time and we don&#8217;t know how long it&#8217;s going to take to get back to a point where we know how long the project is going to take.</p>
<p>So what&#8217;s to be done? Bugs throughout the development life cycle are inevitable &#8211; but because we cannot know how many there will be and how long they will take to fix, we need to be able to minimise the number that crop up.</p>
<p>Some research done by microsoft (http://research.microsoft.com/en-us/groups/ese/nagappan_tdd.pdf) has shown that spending 15-35% extra development time on adopting test driven development resulted in a pre-release defect density decrease of 40-90%.</p>
<p>The ideal is when we can plan, develop and release software that contains no defects in a timescale that everyone agrees on. This wont happen any time soon &#8211; but an increase of 15-35% development time for up to a 90% decrease in the number of defects has *got* to be worth it by anybody&#8217;s standards.</p>
<p>Have you used TDD (or BDD) and experienced similar results? Comments encouraged! </p>
]]></content:encoded>
			<wfw:commentRss>http://nocarrier.co.uk/2012/01/so-you-think-tdd-isnt-worth-the-cost/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>REST and the Hypermedia Constraint</title>
		<link>http://nocarrier.co.uk/2012/01/rest-and-the-hypermedia-constraint/</link>
		<comments>http://nocarrier.co.uk/2012/01/rest-and-the-hypermedia-constraint/#comments</comments>
		<pubDate>Sun, 08 Jan 2012 10:39:33 +0000</pubDate>
		<dc:creator>blongden</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[conference]]></category>
		<category><![CDATA[hypermedia]]></category>
		<category><![CDATA[rest]]></category>

		<guid isPermaLink="false">http://nocarrier.co.uk/?p=111</guid>
		<description><![CDATA[The video of my talk at PHPNW &#8217;11 has now been posted online at blip.tv Enjoy!]]></description>
				<content:encoded><![CDATA[<p>The video of my talk at PHPNW &#8217;11 has now been posted online at <a href="http://blip.tv/phpnw/phpnw11-ben-longden-rest-and-hateoas-a-case-study-5858742">blip.tv</a></p>
<p>Enjoy!</p>
]]></content:encoded>
			<wfw:commentRss>http://nocarrier.co.uk/2012/01/rest-and-the-hypermedia-constraint/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Magento Enterprise PageCache</title>
		<link>http://nocarrier.co.uk/2012/01/magento-enterprise-pagecache/</link>
		<comments>http://nocarrier.co.uk/2012/01/magento-enterprise-pagecache/#comments</comments>
		<pubDate>Thu, 05 Jan 2012 20:28:13 +0000</pubDate>
		<dc:creator>blongden</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[magento]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://nocarrier.co.uk/?p=103</guid>
		<description><![CDATA[I have split this post into two parts &#8211; starting with how pages are cached in the first place, and then how Magento retrieves a page from the cache before falling back to dispatching a controller. How pages are cached The Magento enterprise page cache module observes several events that are fired during the course [...]]]></description>
				<content:encoded><![CDATA[<p>I have split this post into two parts &#8211; starting with how pages are cached in the first place, and then how Magento retrieves a page from the cache before falling back to dispatching a controller.</p>
<p><strong>How pages are cached</strong></p>
<p>The Magento enterprise page cache module observes several events that are fired during the course of dispatching your controller and sending a full page in the response. I&#8217;m going to dive into only a few of them &#8211; the main observers that actually cause your content to end up in the page cache, and then exactly how Magento gets it back out again.</p>
<p>The first thing we&#8217;re going to look at is how Magento caches pages, and that starts with the observation of the &#8216;controller_action_predispatch&#8217; event &#8211; triggered before a request is dispatched (but after we have determined we will not be fulfilling the request from the cache). It&#8217;s here that the PageCache module will determine if the request that&#8217;s about to be dispatched is to be cached for subsequent requests. There are many things that will prevent a page from being cached and we can start by looking at these.</p>
<p>Examine the processPreDispatch method in Enterprise_PageCache_Model_Observer. This is the event that is fired on the controller_action_predispatch event. All the handlers first check to ensure that the page cache is enabled before doing anything else. Then we examine the no cache cookie and set a flag (memorize_disabled) in the session.</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>_processor<span style="color: #339933;">-&gt;</span><span style="color: #004000;">canProcessRequest</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$request</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">&amp;&amp;</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>_processor<span style="color: #339933;">-&gt;</span><span style="color: #004000;">getRequestProcessor</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$request</span><span style="color: #009900;">&#41;</span></pre></td></tr></table></div>

<p>The first of the above two condiditions does some basic validation on the request. $this->_processor will normally be an instance of &#8216;Enterprise_PageCache_Model_Processor&#8217; by this point (it&#8217;s instantiated by the &#8216;enterprise_pagecache/processor&#8217; model here so can be overridden), and here we will find the canProcessRequest method. First, we dip into the isAllowed method where we check that we&#8217;ve generated a requestId during the construction of this object. The requestId will become important later on in the process as it provides the key into your cache storage backend for the page content and needs to be reliably recreated based on the request parameters. We then check that the request is not over https, the no cache cookie (NO_CACHE) is not present, the no_cache GET variable is not present and that full page caching is enabled. If any of these checks fail we do not process this request any further in the full page cache module.</p>
<p>Assuming we pass, we move onto checking the configuration. We inspect the page depth parameter (the number of variations a page can have based on the number of variables in the query string). If we&#8217;re over the limit, the page is not cached. Then we check the cache settings for pages that are not in the default currency (system/page_cache/multicurrency = 0 and the presence of the CURRENCY cookie in the request).</p>
<p>The second of the two checks above is where we examine how the page is going to be cached. This is configured in &#8216;frontend/cache/requests&#8217; and the defaults are found in app/code/core/Enterprise/PageCache/etc/config.xml in the following section of XML. By default all cms, catalog/category and catalog/product pages have a processor configured.</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;frontend<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    ...
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;cache<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;requests<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;cms<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>enterprise_pagecache/processor_default<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/cms<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;catalog<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
                <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;category<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
                    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;view<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>enterprise_pagecache/processor_category<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/view<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
                <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/category<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/catalog<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;catalog<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
                <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;product<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
                    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;view<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>enterprise_pagecache/processor_product<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/view<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
                <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/product<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/catalog<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/requests<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/cache<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/frontend<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></td></tr></table></div>

<p>getRequestProcessor is where this configuration is examined and we we use the request data to attempt to construct a processor for the target page. Assuming one is configured, Magento is now ready to cache the page for the next request.</p>
<p>If at this point it looks as though we&#8217;re going to cache the page, the independent block cache is disabled and the first peice of setting up the cache is complete.</p>
<p>The next time we&#8217;re back in the PageCache code is once the request has been handled and we&#8217;re about to send the response. This is accomplished by hooking into the controller_front_send_response_before event and executing the &#8216;cacheResponse&#8217; method on the observer. We very quickly end up back in the processor and in the processRequestResponse method.</p>
<p>The first two calls will be familiar. The same methods (canProcessRequest and getRequestProcessor) are called again &#8211; however the processor for this request already exists so the second method returns immediately. We delegate to the configured processor (configured above) at this point and call the &#8216;allowCache&#8217; method with the Request object as a parameter. A number of further checks are done which could prevent the request from being cached &#8211; the presence of &#8216;___store&#8217; or &#8216;___from_store&#8217; in the query string (for the default processor) or the presence of the no cache flag in the session data.</p>
<p>Finally we&#8217;re actually ready to cache the response. Some filtering occurs to strip out blocks and replace them with placeholders (blocks can be cached independently from the page &#8211; to allow for independant cache rules &#8211; like the navigation menu which can persist across multiple pages). The placeholder configuration is stored in app/code/core/Enterprise/PageCache/etc/cache.xml and is structured like the following (this is a real example for the catalog/navigation block).</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;config<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;placeholders<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;catalog_navigation<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;block<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>catalog/navigation<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/block<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;name<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>catalog.topnav<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/name<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;placeholder<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>CATALOG_NAVIGATION<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/placeholder<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;container<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>Enterprise_PageCache_Model_Container_Catalognavigation<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/container<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;cache_lifetime<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>86400<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/cache_lifetime<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/catalog_navigation<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/placeholders<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/config<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></td></tr></table></div>

<p>The above peice of XML declares the catalog/navigation block to be cached separately to any page that is appears on with CATALOG_NAVIGATION as the placeholder. It specifies the container class (used during storing and extracting the block) and the lifetime in seconds for the cached block.</p>
<p>Blocks are marked up at the time they are rendered and you can view them in the HTML source code between comment blocks that consist of the placeholder value defined in cache.xml, and a hash that is made up by the md5 sum of the results of calling the getCacheKey. They look something like the following (again, using CATALOG_NAVIGATION as an example).</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #808080; font-style: italic;">&lt;!--{CATALOG_NAVIGATION_a61df2dc9b9e5868f17a56461177d8c4}--&gt;</span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;p<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>some html<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/p<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
<span style="color: #808080; font-style: italic;">&lt;!--/{CATALOG_NAVIGATION_a61df2dc9b9e5868f17a56461177d8c4}--&gt;</span></pre></td></tr></table></div>

<p>This functionality gives you the ability to be able to cache blocks separately to the full page &#8211; with their own rules on how long they stay in the cache for (and independently of the page that they are on). This means that blocks can be made to be cached across pages rather than within them &#8211; meaning that blocks such as catalog/navigation need only be generated once &#8211; and served up from the cache for every request after that regardless of if the page itself is being served from the cache.</p>
<p><strong>How pages are served up from the cache</strong></p>
<p>Rather unlike how pages end up in the cache (using observers to watch for specific points in the dispatch process for a request), the method by which Magento retrieves information from the cache is somewhat more hard coded. Before dispatching the front controller in Mage_Core_Model_App::run (one of the very first methods that gets called in fulfilling a request) a check is done to see if the current request can be served up from the pages in the cache. This happens inside Mage_Core_Model_Cache::processRequest where we immediately check to see if there is a request processor configured that we can check the request against. The request processors are configured inside app/etc/enterprise.xml &#8211; the default one is set to Enterprise_PageCache_Model_Processor (predictably the same class used to cache the results of a dispatched request).</p>
<p>This is quite important &#8211; if you have a reason to extend the logic in Enterprise_PageCache_Model_Processor (like adding data that forms part of the cache id for a page), you not only have to extend it and rewrite &#8216;enterprise_pagecache/processor&#8217;, but also make sure that it&#8217;s added to this list of request processors so that Magento has a chance of being able to retrieve your items back out of the cache again.</p>
<p>Magento then loops through all the configured request processors, and calls extractContent on each of them. The first thing that this function does is create the cache id based on the request parameters (this happens when the processor is constructed, when the _createRequestIds method is called &#8211; as we saw earlier when the content was being cached in the first place). We check to see if any design changes have been cached for the current page, and then check the configured cache storage to see if we can retrieve the full page content for this request. If we do not get a match at this point, the request is considered a cache miss &#8211; and we return to the run method and start the process of dispatching the request (and potentially populating the cache with the results).</p>
<p>Assuming that we have a cache hit, we decompress it (content will be gzipped whenever possible in the cache storage to minimise space), and the content is processed by _processContent to replace all of the placeholders with separate cached blocks (ie, the catalog/navigation block that we cached separately when putting the page into the cache in the first place).</p>
<p>When writing about how pages are served up from the cache I referred to the configured cache storage. Prior to Magento EE 1.11, the full page cache simply used what you configured in the <cache></cache> section in app/etc/local.xml. From 1.11 this has changed and you must now also have a <full_page_cache></full_page_cache> section in your local.xml configuration (it uses exactly the same options as the <cache></cache> config).</p>
<p>The aim of this post is to give an overview of how page caching works in magento and I am intending on following it up with some more detailed investigations into how more areas of cacheing work. If you have a specific request for more information, please do leave a comment and it may form part of a future blog post.</p>
]]></content:encoded>
			<wfw:commentRss>http://nocarrier.co.uk/2012/01/magento-enterprise-pagecache/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
	</channel>
</rss>
<!-- This Quick Cache file was built for (  nocarrier.co.uk/feed/ ) in 0.90776 seconds, on May 19th, 2013 at 9:28 pm UTC. -->
<!-- This Quick Cache file will automatically expire ( and be re-built automatically ) on May 19th, 2013 at 10:28 pm UTC -->
<!-- +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
<!-- Quick Cache Is Fully Functional :-) ... A Quick Cache file was just served for (  nocarrier.co.uk/feed/ ) in 0.00072 seconds, on May 19th, 2013 at 10:14 pm UTC. -->