<?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>Uncarved &#187; plugin</title>
	<atom:link href="http://uncarved.prometheas.com/tag/plugin/feed" rel="self" type="application/rss+xml" />
	<link>http://uncarved.prometheas.com</link>
	<description>An ongoing tension of potential, or how i learned to stop worrying and embrace the iterations.</description>
	<lastBuildDate>Mon, 08 Aug 2011 05:14:30 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.4</generator>
		<item>
		<title>Designing the sfRESTClientPlugin: Sketching a Client API for RESTful Interactions</title>
		<link>http://uncarved.prometheas.com/2009/06/sketching-a-client-api-for-restful-interactions.html</link>
		<comments>http://uncarved.prometheas.com/2009/06/sketching-a-client-api-for-restful-interactions.html#comments</comments>
		<pubDate>Mon, 01 Jun 2009 05:41:25 +0000</pubDate>
		<dc:creator>John</dc:creator>
				<category><![CDATA[Public Brainstorm]]></category>
		<category><![CDATA[API]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[plugin]]></category>
		<category><![CDATA[proposal]]></category>
		<category><![CDATA[REST]]></category>
		<category><![CDATA[sfRESTClientPlugin]]></category>
		<category><![CDATA[Symfony]]></category>

		<guid isPermaLink="false">http://uncarved.prometheas.com/?p=373</guid>
		<description><![CDATA[I&#8217;ve lately been exploring the value proposition of RESTful APIs to organizations whose technological infrastructures are built upon a collection of legacy software components, customized to communicate with each other by highly tailored middleware software stacks. That exploration will not unfold in this post, however. It could easily be an entire book unto itself. Rather, [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve lately been exploring the value proposition of RESTful APIs to organizations whose technological infrastructures are built upon a collection of legacy software components, customized to communicate with each other by highly tailored middleware software stacks.</p>

<p>That exploration will not unfold in this post, however. It could easily be an entire book unto itself.</p>

<p>Rather, I would like to focus specifically on ideas I&#8217;ve had about what a high level object oriented API for interacting with RESTful services might look like, and funnel those thoughts into the design and implementation of a plugin I&#8217;m developing for the <a href="http://www.symfony-project.org">Symfony framework</a>, called <a href="http://www.symfony-project.org/plugins/sfRESTClientPlugin">sfRESTClientPlugin</a>.</p>

<h3>Audience and Scope</h3>

<p>This post assumes at least casual familiarity with Web development. I will explore some general principles of the RESTful interaction paradigm, but only to the extent to which they inform the design direction of the plugin&#8217;s API.</p>

<p>Although all the code samples will be in PHP, it is my hope that the exercise will yield material valuable to people working with other software stacks.</p>

<p><span id="more-373"></span></p>

<h3>The Fundamentals</h3>

<p>Wikipedia offers a great <a href="http://en.wikipedia.org/wiki/Representational_State_Transfer">article</a> describing REST that is worth reading, if you would like a quick brush-up or introduction to the concept. I would describe REST as an &#8220;organic&#8221; extension to the model around which the World Wide Web itself was designed, as it wholly embraces a model composed of resources (text, images, videos, etc) that can be accessed using specific URLs.</p>

<p>I&#8217;ll be using the following assertion from the article as the springboard for my API design considerations (emphasis added to highlight the principal entities):</p>

<blockquote>
  <p>An important concept in REST is the existence of resources (sources of specific information), each of which is referenced with a global identifier (e.g., a URI in HTTP). In order to manipulate these resources, components of the network (user agents and origin servers) communicate via a standardized interface (e.g., HTTP) and exchange representations of these resources (the actual documents conveying the information).</p>
</blockquote>

<p>The API will therefore designed around the following discreet entities:</p>

<ul>
<li>Service</li>
<li>Resource</li>
<li>Client (or &#8220;user agent&#8221;)</li>
<li>Request</li>
<li>Response</li>
</ul>

<p>Another design goal for the plugin is that it offers the integration mechanisms that developers familiar with Symfony (and other high-quality MVC frameworks) will find familiar, such as named routes, YAML project configuration, <a href="http://en.wikipedia.org/wiki/Don%27t_repeat_yourself">DRY</a> design, and an environment-aware configuration cascade.</p>

<h3>A Sneak Peak</h3>

<p>At a certain point, examples speak more clearly than theories and principles. For the remainder of this post, I will talk about a sample REST service, which represents a &#8220;traditional&#8221; library — a collection of books.</p>

<p>The primary entities with which your site&#8217;s business logic will be dealing with are the <em>services</em> themselves, each which offer one or more <em>resources</em>. Each service is defined by a collection of properties that declare information such as its host name, the types of resources available from the service, authentication credentials, and perhaps smaller details like a port number, root URI, etc.</p>

<p>A sample configuration might look like this:</p>

<pre><code>  [#!yaml]
  # config/rest_services.yml
  services:
    service_1:
      scheme  : https
      host    : exampleservice.com
      root_uri: /api

      resources:

        book:
          list: /books.xml
          item: /books/:id.xml

        author:
          list: /authors.xml
          item: /authors/:id.xml
</code></pre>

<p>The RESTful service in our example is located at <code>https://exampleservice.com/api</code> and offers two resource entities: <code>book</code> and <code>author</code>. These configuration values will be used to populate the properties of a <code>sfRESTOriginService</code> instance that represents the service.</p>

<p>Note that this configuration is defined under the key <code>service_1</code>. Here&#8217;s what some code that interacts with this service might look like:</p>

<pre><code>  [#!php]
  $svc = sfRESTOriginService::getInstance( 'service_1' );

  // GET https://exampleservice.com/api/articles/34.xml
  $response = $svc-&gt;get( '@book?id=34' );

  // make sure we have a valid response
  if ( $response-&gt;isError() )
  {
    if ( $response-&gt;isStatusCode( sfRESTClient::STATUS_UNAUTHORIZED ) )
    {
      throw new Exception( 'Access to resource is unauthorized!' );
    }
    else
    {
      throw new Exception( 'An error occurred attempting to access the resource!' );
    }
  }

  // load the XML into a locally defined entity and manipulate it
  $book = new MyLocalBook();
  $book-&gt;loadFromXML( $response-&gt;getResponseXML() );
  $book-&gt;setTitle( 'A New Title' );

  // PUT https://exampleservice.com/api/articles/34.xml
  $svc-&gt;put( '@book?id=34', array(
    'data' =&gt; $book-&gt;serializeXml()
  ));
</code></pre>

<p>As the sample suggests, each service will be represented by a single instance.</p>

<p>Each service naturally supports the four <a href="http://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Request_methods">HTTP methods</a> used by REST: <code>GET</code>, <code>POST</code>, <code>PUT</code>, and <code>DELETE</code>, so requests of these method types are issued by invoking the corresponding class methods of a <code>sfRESTOriginService</code> instance.</p>

<p>The <code>GET</code> method requires only a URI, indicating the desired resource.</p>

<p>Each request to the service produces a response object, which offers access to the resource data in question. The response object also provides access to response information such as HTTP headers, the resource URL, the request method used for the query that created it, and the <a href="http://en.wikipedia.org/wiki/List_of_HTTP_status_codes">HTTP status code</a>.</p>

<p>Each method must be performed against a particular URI, which must be specified, and the <code>PUT</code> and <code>POST</code> methods also require a data payload.</p>

<h3>Parting Thoughts</h3>

<p>This post is simply a starting point; a sketch. I will follow up shortly with another post outlining deeper use cases, such as using the <code>POST</code> method to create new resources, and dealing with resources of different data types, such as JSON, plain text, or even media files.</p>

<p>In the meantime, I welcome any thoughts or questions regarding this initial direction.</p>

<p>One particular matter I&#8217;m not so hot on from the examples above is the way in which resources are defined in the service configuration. I wonder if there isn&#8217;t some better way to express the resource configuration, and manage to still deliver the &#8220;named route&#8221;-like approach to specifying resource URIs shown in the sample code above.</p>
<!-- PHP 5.x -->]]></content:encoded>
			<wfw:commentRss>http://uncarved.prometheas.com/2009/06/sketching-a-client-api-for-restful-interactions.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

