<?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>Gen X Design &#124; Ian Selby &#187; REST</title>
	<atom:link href="http://www.gen-x-design.com/tags/rest/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.gen-x-design.com</link>
	<description>Just another WordPress weblog</description>
	<lastBuildDate>Fri, 15 Jan 2010 21:41:43 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Making RESTful Requests in PHP</title>
		<link>http://www.gen-x-design.com/archives/making-restful-requests-in-php/</link>
		<comments>http://www.gen-x-design.com/archives/making-restful-requests-in-php/#comments</comments>
		<pubDate>Thu, 14 May 2009 19:47:03 +0000</pubDate>
		<dc:creator>Ian</dc:creator>
				<category><![CDATA[AJAX]]></category>
		<category><![CDATA[Off Topic]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[DELETE]]></category>
		<category><![CDATA[GET]]></category>
		<category><![CDATA[POST]]></category>
		<category><![CDATA[PUT]]></category>
		<category><![CDATA[Request]]></category>
		<category><![CDATA[REST]]></category>

		<guid isPermaLink="false">http://www.gen-x-design.com/?p=269</guid>
		<description><![CDATA[APIs have become a very commonplace part of many popular web sites and services&#8230; especially REST APIs.  I&#8217;ve already discussed how you can roll your own REST API for your PHP apps, but I&#8217;ve also received countless requests to go over how to actually make RESTful requests.  That&#8217;s exactly what we&#8217;ll take a [...]]]></description>
			<content:encoded><![CDATA[<p>APIs have become a very commonplace part of many popular web sites and services&#8230; especially REST APIs.  I&#8217;ve already <a href="http://www.gen-x-design.com/archives/create-a-rest-api-with-php/">discussed</a> how you can roll your own REST API for your PHP apps, but I&#8217;ve also received countless requests to go over how to actually make RESTful requests.  That&#8217;s exactly what we&#8217;ll take a look at in this article.  Before we dive in, however, I want to make sure you&#8217;ve got a basic understanding of how REST APIs work, so if you&#8217;re a bit shaky or unfamiliar with the concept, head on over to my <a href="http://www.gen-x-design.com/archives/create-a-rest-api-with-php/">previous article on REST</a> and read up (you don&#8217;t need to go over the implementation stuff if you don&#8217;t want, just read the first part of the article).  Seriously, do it&#8230; this article is written with the assumption you&#8217;re familiar with the concepts of REST.</p>
<p>Anyway, without any further delay, let&#8217;s take a look at what we&#8217;re going to cover&#8230;<br />
<span id="more-269"></span></p>
<h2>The Basics of a RESTful Request</h2>
<p>Every REST request consists of essentially the same basic parts:</p>
<ul>
<li><strong>The URL</strong> &#8211; This is the URL we&#8217;ll be making a request against (often referred to as a resource).</li>
<li><strong>The Verb</strong> &#8211; GET, POST, PUT, or DELETE&#8230; there are some others out there, but these are the 4 most common ones.</li>
<li><strong>The Params</strong> &#8211; The parameters we&#8217;ll be supplying to the API, often referred to as the request body.</li>
<li><strong>Credentials</strong> &#8211; Username and password&#8230; we&#8217;ll cover HTTP Digest auth credentials.</li>
</ul>
<p>And, of course, we&#8217;ll have a few pieces for our response as well:</p>
<ul>
<li><strong>The Response Body</strong> &#8211; The actual response body the API gave us.</li>
<li><strong>The Response Status Code</strong> &#8211; The HTTP status code the API responded with.</li>
<li><strong>Other Response Info</strong> &#8211; We&#8217;ll also have some other interesting info in the response.</li>
</ul>
<p>Nothing really unexpected here, everything&#8217;s probably looking like what you&#8217;d expect: a request and a response.</p>
<p>So, on to the answer to the most important question: &#8220;How the heck do you actually make the request?!?!?&#8221;</p>
<h2>REST &amp; PHP &#8211; Curl to the Rescue</h2>
<p>You may have already guessed we&#8217;d be using curl (or suspected it perhaps)&#8230; and if you didn&#8217;t, well, that&#8217;s what we&#8217;ll be using <img src='http://www.gen-x-design.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />   Anyway, if you&#8217;ve ever worked with Curl in PHP, you&#8217;re probably aware that making GET and POST requests are pretty straight-forward, but the PUT and DELETE requests are a little less obvious.  Luckily, they&#8217;re pretty easy once you know how to do them, the problem is that they&#8217;re very poorly documented.  We&#8217;ll go over them soon, but let&#8217;s get started with a little code.  We&#8217;re going to be building a class that we can use to make requests and deal with their responses, so why don&#8217;t we build up a bit of a base class, and then start filling things in:</p>
<pre name="code" class="php">
class RestRequest
{
	protected $url;
	protected $verb;
	protected $requestBody;
	protected $requestLength;
	protected $username;
	protected $password;
	protected $acceptType;
	protected $responseBody;
	protected $responseInfo;

	public function __construct ($url = null, $verb = 'GET', $requestBody = null)
	{
		$this->url				= $url;
		$this->verb				= $verb;
		$this->requestBody		= $requestBody;
		$this->requestLength		= 0;
		$this->username			= null;
		$this->password			= null;
		$this->acceptType		= 'application/json';
		$this->responseBody		= null;
		$this->responseInfo		= null;

		if ($this->requestBody !== null)
		{
			$this->buildPostBody();
		}
	}

	public function flush ()
	{
		$this->requestBody		= null;
		$this->requestLength		= 0;
		$this->verb				= 'GET';
		$this->responseBody		= null;
		$this->responseInfo		= null;
	}

	public function execute ()
	{

	}

	public function buildPostBody ($data = null)
	{

	}

	protected function executeGet ($ch)
	{		

	}

	protected function executePost ($ch)
	{

	}

	protected function executePut ($ch)
	{

	}

	protected function executeDelete ($ch)
	{

	}

	protected function doExecute (&#038;$curlHandle)
	{

	}

	protected function setCurlOpts (&#038;$curlHandle)
	{

	}

	protected function setAuth (&#038;$curlHandle)
	{

	}
}
</pre>
<p>So, what we&#8217;ve got here is essentially all of the functions we&#8217;ll need to make this whole thing work right.  We&#8217;ll cover each of the function individually, but let&#8217;s take a look at the class members:</p>
<ul>
<li><strong>$url</strong> &#8211; The URL we&#8217;ll be requesting against</li>
<li><strong>$verb</strong> &#8211; The type of request we&#8217;ll be making (what verb to use)</li>
<li><strong>$requestBody</strong> &#8211; The request body we&#8217;ll send with PUT and POST requests</li>
<li><strong>$requestLength</strong> &#8211; An internally used variable for PUT requests (more on this later)</li>
<li><strong>$username</strong> &#8211; The username to use for this request</li>
<li><strong>$password</strong> &#8211; I&#8217;ll let you guess <img src='http://www.gen-x-design.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </li>
<li><strong>$acceptType</strong> &#8211; What kind of content we&#8217;ll accept as a response (not all APIs use this to determine the response format, but we&#8217;ll be robust)</li>
<li><strong>$responseBody</strong> &#8211; The body of our response</li>
<li><strong>$responseInfo</strong> &#8211; All the other goodness from our response (status code, etc.)</li>
</ul>
<p>Not too rough, right?  And if you take a look at the constructor, you&#8217;ll see things are pretty straight-forward as well.  We&#8217;ve also got a flush function.  This allows us to use the same object to make multiple requests by only clearing out certain member variables (notice username / password aren&#8217;t touched).  You may have also noticed we&#8217;re missing getters / setters&#8230; this is simply to keep the code a little shorter.  The final class will have them.</p>
<h2>Making Requests &#8211; The Prep Work</h2>
<p>Let&#8217;s go ahead and fill in some of the functions that do prep work for us, and then we&#8217;ll dig into making the requests.  Anyway, let&#8217;s take a look at these &#8220;init&#8221; functions..</p>
<p><strong>buildPostBody</strong><br />
This function will take an array and prepare it for being posted (or put as well):</p>
<pre name="code" class="php">
	public function buildPostBody ($data = null)
	{
		$data = ($data !== null) ? $data : $this->requestBody;

		if (!is_array($data))
		{
			throw new InvalidArgumentException('Invalid data input for postBody.  Array expected');
		}

		$data = http_build_query($data, '', '&#038;');
		$this->requestBody = $data;
	}
</pre>
<p>Notice how we will throw exceptions if we receive anything other than an array?  This is important, as we don&#8217;t want our data to be malformed (or an error to be thrown by http_build_query).  Also, you may be thinking that I&#8217;m using an exception type that isn&#8217;t defined anywhere&#8230; well, it is (if you&#8217;re using PHP 5).  I won&#8217;t go off on a tangent, but check out the <a href="http://php.net/spl" target="_blank">PHP SPL</a> for more info.  All you need to know is that the InvalidArgumentException is already defined for you <img src='http://www.gen-x-design.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p><strong>setCurlOpts</strong><br />
This function will take care of all the curl options common to all our requests:</p>
<pre name="code" class="php">
	protected function setCurlOpts (&#038;$curlHandle)
	{
		curl_setopt($curlHandle, CURLOPT_TIMEOUT, 10);
		curl_setopt($curlHandle, CURLOPT_URL, $this->url);
		curl_setopt($curlHandle, CURLOPT_RETURNTRANSFER, true);
		curl_setopt($curlHandle, CURLOPT_HTTPHEADER, array ('Accept: ' . $this->acceptType));
	}
</pre>
<p><strong>setAuth</strong><br />
If we&#8217;ve got a username and password set on the class, we&#8217;ll set up the auth options on the curl request with this function:</p>
<pre name="code" class="php">
	protected function setAuth (&#038;$curlHandle)
	{
		if ($this->username !== null &#038;&#038; $this->password !== null)
		{
			curl_setopt($curlHandle, CURLOPT_HTTPAUTH, CURLAUTH_DIGEST);
			curl_setopt($curlHandle, CURLOPT_USERPWD, $this->username . ':' . $this->password);
		}
	}
</pre>
<p>I mentioned earlier that we&#8217;re only going to cover HTTP Digest authentication in this class, but you could adapt this function to suit your needs however you wanted depending on what the API(s) you&#8217;re consuming require.</p>
<h2>Making the REST Requests</h2>
<p>We&#8217;re about ready to cover how to make the individual verb requests, but we need to do just a little bit more work filling in the common functionality.  We&#8217;ll go ahead and create our doExecute and execute functions now:</p>
<pre name="code" class="php">
	public function execute ()
	{
		$ch = curl_init();
		$this->setAuth($ch);

		try
		{
			switch (strtoupper($this->verb))
			{
				case 'GET':
					$this->executeGet($ch);
					break;
				case 'POST':
					$this->executePost($ch);
					break;
				case 'PUT':
					$this->executePut($ch);
					break;
				case 'DELETE':
					$this->executeDelete($ch);
					break;
				default:
					throw new InvalidArgumentException('Current verb (' . $this->verb . ') is an invalid REST verb.');
			}
		}
		catch (InvalidArgumentException $e)
		{
			curl_close($ch);
			throw $e;
		}
		catch (Exception $e)
		{
			curl_close($ch);
			throw $e;
		}

	}

	protected function doExecute (&#038;$curlHandle)
	{
		$this->setCurlOpts($curlHandle);
		$this->responseBody = curl_exec($curlHandle);
		$this->responseInfo	= curl_getinfo($curlHandle);

		curl_close($curlHandle);
	}
</pre>
<p>Looks like a lot of code, but it&#8217;s actually pretty simple stuff.  </p>
<p>First, looking at execute, you&#8217;ll see that we set up a curl handle variable ($ch), and then run the setAuth function.  Since we pass $ch around by reference, the functions will directly manipulate the variable without any need to return it.  Now, I could make the $ch a member variable, but for the sake of this example, I wanted to show how everything gets passed around a little more explicitly.  Anyway, the next thing we do is normalize the verb, and run through our switch statement to determine what function will get executed.  If we don&#8217;t find a matching case, we throw an exception.  We also wrap the whole thing in a try / catch block so we can properly catch exceptions, close our curl handle, then throw the exception again (presumably for some other error handler or try / catch block elsewhere in the code).</p>
<p>Moving on to the doExecute function, you&#8217;ll see all we really do here is set all the common curl options with setCurlOpts, execute the request, and get the response body and info.  We&#8217;ll take a look at those in a bit, but let&#8217;s get to the individual request functions.</p>
<h2>GET Requests</h2>
<p>These requests are about as easy as they get.  Since your params will be a part of the URL, there isn&#8217;t much to do outside of actually making the request.  So our code is nice and easy:</p>
<pre name="code" class="php">
	protected function executeGet ($ch)
	{
		$this->doExecute($ch);
	}
</pre>
<p>&#8216;Nuff said <img src='http://www.gen-x-design.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<h2>POST Requests</h2>
<p>These too are pretty easy to accomplish, and POSTing with Curl is well-documented.  Nonetheless, here&#8217;s what our function looks like:</p>
<pre name="code" class="php">
	protected function executePost ($ch)
	{
		if (!is_string($this->requestBody))
		{
			$this->buildPostBody();
		}

		curl_setopt($ch, CURLOPT_POSTFIELDS, $this->requestBody);
		curl_setopt($ch, CURLOPT_POST, 1);

		$this->doExecute($ch);
	}
</pre>
<p>All we really do here is make sure the request body is a string, and if it isn&#8217;t that means we need to prepare it&#8230; so we do.  Then we tell Curl to make a POST request with the provided POST body.  That&#8217;s all there is to it!  Moving on&#8230;</p>
<h2>PUT Requests in PHP</h2>
<p>Ah, PUT requests&#8230;  These are the big mystery.  Admittedly, there are a few articles out there covering how to do them, but they&#8217;re not super-easy to come across.  I did, however, manage to find a few and here&#8217;s what I came up with:</p>
<pre name="code" class="php">
	protected function executePut ($ch)
	{
		if (!is_string($this->requestBody))
		{
			$this->buildPostBody();
		}

		$this->requestLength = strlen($this->requestBody);

		$fh = fopen('php://memory', 'rw');
		fwrite($fh, $this->requestBody);
		rewind($fh);

		curl_setopt($ch, CURLOPT_INFILE, $fh);
		curl_setopt($ch, CURLOPT_INFILESIZE, $this->requestLength);
		curl_setopt($ch, CURLOPT_PUT, true);

		$this->doExecute($ch);

		fclose($fh);
	}
</pre>
<p>A little funky, right?  Well, this boils down to the way PUT requests are technically supposed to work.  RESTful APIs don&#8217;t quite use a PUT the way they were originally intended, which is for file uploads.  As such, we need to stream the data to the web server.  So we open an internal php memory resource, write our request body to it, and then pass the handle for that memory resource to curl.  We also calculate the size of it (in bytes), so that our full body will be received on the API side of things.  I suppose that doesn&#8217;t necessarily need to make any sense to you, as long as you trust that it works <img src='http://www.gen-x-design.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<h2>DELETE Requests in PHP</h2>
<p>Deletes, when done as they&#8217;re intended (no post body), are easy.  Remember, you&#8217;re not really supposed to send any body for a delete request, as you&#8217;re merely sending a command to a resource (i.e. /api/user/1).  Here&#8217;s the code:</p>
<pre name="code" class="php">
	protected function executeDelete ($ch)
	{
		curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'DELETE');

		$this->doExecute($ch);
	}
</pre>
<p>Now, if you need to send a body for some reason, you can do it by adding the same stuff you use for a PUT request, but swap out the CURLOPT_PUT line for the existing CURLOPT_CUSTOMREQUEST line that we&#8217;ve got in this function.  I don&#8217;t advocate this, but it works like a champ if you need it.</p>
<h2>The Response</h2>
<p>Now that we&#8217;ve got a fully functioning REST requester, let&#8217;s take a look at a response.  So, making a request against an imaginary API looks something like:</p>
<pre name="code" class="php">
$request = new RestRequest('http://example.com/api/user/1', 'GET');
$request->execute();

echo '&lt;pre&gt;' . print_r($request, true) . '&lt;/pre&gt;';
</pre>
<p>Which gives us output similar to:</p>
<pre name="code">
RestRequest Object
(
    [url:protected] => http://example.com/api/user/1
    [verb:protected] => GET
    [requestBody:protected] =>
    [requestLength:protected] => 0
    [username:protected] =>
    [password:protected] =>
    [acceptType:protected] => application/json
    [responseBody:protected] => [RESPONSE BODY HERE]
    [responseInfo:protected] => Array
        (
            [url] => http://example.com/api/user/1
            [content_type] => application/json
            [http_code] => 200
            [header_size] => 232
            [request_size] => 192
            [filetime] => -1
            [ssl_verify_result] => 0
            [redirect_count] => 0
            [total_time] => 0.015693
            [namelookup_time] => 0.0004
            [connect_time] => 0.000571
            [pretransfer_time] => 0.000619
            [size_upload] => 0
            [size_download] => 4276
            [speed_download] => 272478
            [speed_upload] => 0
            [download_content_length] => 4276
            [upload_content_length] => 0
            [starttransfer_time] => 0.015655
            [redirect_time] => 0
        )
)
</pre>
<p>Take a look at the responseInfo&#8230; we&#8217;ve got our status code, and all sorts of other good stuff.  And, believe it or not, we&#8217;re done!</p>
<h2>Wrapping Up</h2>
<p>Of course, as with all my samples, there&#8217;s a lot left for you to do.  You&#8217;ll probably want to do some processing of the response body and info (such as extracting the status code), or make a few things more robust, but this is all you should need to get started.  Hopefully, after this article and the previous one, you&#8217;ve got a good idea of how REST APIs work from the server-side, to the client-side, and you&#8217;re ready to jump on the REST bandwagon.  If you&#8217;re not yet convinced&#8230; go play with some SOAP APIs, that ought to change your mind <img src='http://www.gen-x-design.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p>Finally, you can grab the final copy of the class, complete with getters / setters at the link below:<br />
<a href='http://www.gen-x-design.com/wp-content/uploads/2009/05/restrequestincphp1.zip'>RestRequest.inc.php &#8211; Final Source Code</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.gen-x-design.com/archives/making-restful-requests-in-php/feed/</wfw:commentRss>
		<slash:comments>28</slash:comments>
		</item>
		<item>
		<title>Create a REST API with PHP</title>
		<link>http://www.gen-x-design.com/archives/create-a-rest-api-with-php/</link>
		<comments>http://www.gen-x-design.com/archives/create-a-rest-api-with-php/#comments</comments>
		<pubDate>Wed, 18 Feb 2009 23:07:13 +0000</pubDate>
		<dc:creator>Ian</dc:creator>
				<category><![CDATA[AJAX]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[API]]></category>
		<category><![CDATA[REST]]></category>

		<guid isPermaLink="false">http://www.gen-x-design.com/?p=235</guid>
		<description><![CDATA[]]></description>
			<content:encoded><![CDATA[<div style="text-align: center"><img style="margin-top: 10px; margin-bottom: 10px; padding: 2px; border: 1px solid #ccc;"src="http://www.gen-x-design.com/wp-content/uploads/2009/02/rest-apis1.png" alt=Create a REST API with PHP" title="Create a REST API with PHP" width="580" height="120" /></div>
<p>One of the latest (sort of) crazes sweeping the net is APIs, more specifically those that leverage REST.  It&#8217;s really no surprise either, as consuming REST APIs is so incredibly easy&#8230; in any language.  It&#8217;s also incredibly easy to create them as you essentially use nothing more than an HTTP spec that has existed for ages.  One of the few things that I give Rails credit for is its well thought-out REST support, both for providing and consuming these APIs (as its been explained by all the Rails fanboys I work with).</p>
<p>Seriously, if you&#8217;ve never used REST, but you&#8217;ve ever had to work with (or worse, create) a SOAP API, or simply opened a <a href="http://soap.amazon.com/schemas2/AmazonWebServices.wsdl" target="_blank">WSDL</a> and had your head explode, boy do I have good news for you!<br />
<span id="more-235"></span></p>
<h2>So, What on Earth is REST?  Why Should You Care?</h2>
<p>Before we get into writing some code, I want to make sure everyone&#8217;s got a good understanding of what REST is and how its great for APIs.  First, technically speaking, REST isn&#8217;t specific to just APIs, it&#8217;s more of a generic concept.  However, obviously, for the sake of this article we&#8217;ll be talking about it in the context of an API.  So, let&#8217;s look at the basic needs of an API and how REST addresses them.</p>
<p><strong>Requests</strong><br />
All APIs need to accept requests.  Typically, with a RESTful API, you&#8217;ll have a well-defined URL scheme.  Let&#8217;s say you want to provide an API for users on your site (I know, I always use the &#8220;users&#8221; concept for my examples).  Well, your URL structure would probably be something like, &#8220;api/users&#8221; and &#8220;api/users/[id]&#8221; depending on the type of operation being requested against your API.  You also need to consider how you want to accept data.  These days a lot of people are using JSON or XML, and I personally prefer JSON because it works well with JavaScript, and PHP has easy functionality for encoding and decoding it.  If you wanted your API to be really robust, you could accept both by sniffing out the content-type of the request (i.e. application/json or application/xml), but it&#8217;s perfectly acceptable to restrict things to one content type.  Heck, you could even use simple key/value pairs if you wanted.</p>
<p>The other piece of a request is what it&#8217;s actually meant to do, such as load, save, etc.  Normally, you&#8217;d have to come up with some sort of architecture that defines what action the requester (consumer) desires, but REST simplifies that.  By using HTTP request methods, or verbs, we don&#8217;t need to define anything.  We can just use the GET, POST, PUT, and DELETE methods, and that covers every request we&#8217;d need.  You can equate the verbs to your standard crud-style stuff: GET = load/retrieve, POST = create, PUT = update, DELETE = well, delete.  It&#8217;s important to note that these verbs don&#8217;t directly translate to CRUD, but it is a good way to think about them.  So, going back to the above URL examples, let&#8217;s take a look at what some possible requests could mean:</p>
<ul>
<li><strong>GET request to /api/users</strong> &#8211; List all users</li>
<li><strong>GET request to /api/users/1</strong> &#8211; List info for user with ID of 1</li>
<li><strong>POST request to /api/users</strong> &#8211; Create a new user</li>
<li><strong>PUT request to /api/users/1</strong> &#8211; Update user with ID of 1</li>
<li><strong>DELETE request to /api/users/1</strong> &#8211; Delete user with ID of 1</li>
</ul>
<p>As you hopefully see, REST has already taken care of a lot of the major headaches of creating your own API through some simple, well-understood standards and protocols, but there&#8217;s one other piece to a good API&#8230;</p>
<p><strong>Responses</strong><br />
So, REST handles requests very easily, but it also makes generating responses easy.  Similar to requests, there are two main components of a RESTful response: the response body, and a status code.  The response body is pretty easy to deal with.  Like requests, most responses in REST are usually either JSON or XML (perhaps just plain text in the case of POSTs, but we&#8217;ll cover that later).  And, like requests, the consumer can specify the response type they&#8217;d like through another part of the HTTP request spec, &#8220;Accept&#8221;.  If a consumer wishes to receive an XML response, they&#8217;d just send an Accept header as a part of their request saying as much (&#8221;Accept: application/xml&#8221;).  Admittedly, this method isn&#8217;t as widely adopted (tho it should be), so you have can also use the concept of an extension in the URL.  For example, /api/users.xml means the consumer wants XML as a response, similarly /api/users.json means JSON (same for things like /api/users/1.json/xml).  Either way you choose (I say do both), you should pick a default response type as a lot of the time people wont&#8217; even tell you what they want.  Again, I&#8217;d say go with JSON.  So, no Accept header or extension (i.e. /api/users) should not fail, it should just fail-over to the default response-type.</p>
<p>But what about errors and other important status messages associated with requests?  Easy, use HTTP status codes!  This is far and above one of my favorite things about creating RESTful APIs.  By using HTTP status codes, you don&#8217;t need to come up with a error / success scheme for your API, it&#8217;s already done for you.  For example, if a consumer POSTS to /api/users and you want to report back a successful creation, simply send a 201 status code (201 = Created).  If it failed, send a 500 if it failed on your end (500 = Internal Server Error), or perhaps a 400 if they screwed up (400 = Bad request).  Maybe they&#8217;re trying to POST against an API endpoint that doesn&#8217;t accept posts&#8230; send a 501 (Not implemented).  Perhaps your MySQL server is down, so your API is temporarily borked&#8230; send a 503 (Service unavailable).  Hopefully, you get the idea.  If you&#8217;d like to read up a bit on status codes, check them out on wikipedia: <a href="http://en.wikipedia.org/wiki/List_of_HTTP_status_codes" target="_blank">List of HTTP Status Codes</a>.</p>
<p>I&#8217;m hoping you see all the advantages you get by leveraging the concepts of REST for your APIs.  It really is super-cool, and its a shame its not more widely talked about in the PHP community (at least as far as I can tell).  I think this is likely due to the lack of good documentation on how to deal with requests that aren&#8217;t GET or POST, namely PUT and DELETE.  Admittedly, it is a bit goofy dealing with these, but it certainly isn&#8217;t hard.  I&#8217;m also sure some of the popular frameworks out there probably have some sort of REST implementation, but I&#8217;m not a huge framework fan (for a lot of reasons that I won&#8217;t get into), and it&#8217;s also good to know these things even if somebody&#8217;s already created the solution for you.</p>
<p>If you&#8217;re still not convinced that this is a useful API paradigm, take a look at what REST has done for Ruby on Rails.  One of its major claims to fame is how easy it is to create APIs (through some sort of RoR voodoo, I&#8217;m sure), and rightly so.  Granted I know very little about RoR, but the fanboys around the office have preached this point to me many times.  But, I digress&#8230; let&#8217;s write some code!</p>
<h2>Getting Started with REST and PHP</h2>
<p>One last disclaimer:  the code we&#8217;re about to go over is in no way intended to be used as an example of a robust solution.  My main goal here is to show how to deal with the individual components of REST in PHP, and leave creating the final solution up to you.</p>
<p>So, let&#8217;s dig in!  I think the best way to do something practical is to create a class that will provide all the utility functions we need to create a REST API.  We&#8217;ll also create a small class for storing our data. You could also then take this, extend it, and apply it to your own needs.  So, let&#8217;s stub some stuff out:</p>
<pre name="code" class="php">
class RestUtils
{
	public static function processRequest()
	{

	}

	public static function sendResponse($status = 200, $body = '', $content_type = 'text/html')
	{

	}

	public static function getStatusCodeMessage($status)
	{
		// these could be stored in a .ini file and loaded
		// via parse_ini_file()... however, this will suffice
		// for an example
		$codes = Array(
		    100 => 'Continue',
		    101 => 'Switching Protocols',
		    200 => 'OK',
		    201 => 'Created',
		    202 => 'Accepted',
		    203 => 'Non-Authoritative Information',
		    204 => 'No Content',
		    205 => 'Reset Content',
		    206 => 'Partial Content',
		    300 => 'Multiple Choices',
		    301 => 'Moved Permanently',
		    302 => 'Found',
		    303 => 'See Other',
		    304 => 'Not Modified',
		    305 => 'Use Proxy',
		    306 => '(Unused)',
		    307 => 'Temporary Redirect',
		    400 => 'Bad Request',
		    401 => 'Unauthorized',
		    402 => 'Payment Required',
		    403 => 'Forbidden',
		    404 => 'Not Found',
		    405 => 'Method Not Allowed',
		    406 => 'Not Acceptable',
		    407 => 'Proxy Authentication Required',
		    408 => 'Request Timeout',
		    409 => 'Conflict',
		    410 => 'Gone',
		    411 => 'Length Required',
		    412 => 'Precondition Failed',
		    413 => 'Request Entity Too Large',
		    414 => 'Request-URI Too Long',
		    415 => 'Unsupported Media Type',
		    416 => 'Requested Range Not Satisfiable',
		    417 => 'Expectation Failed',
		    500 => 'Internal Server Error',
		    501 => 'Not Implemented',
		    502 => 'Bad Gateway',
		    503 => 'Service Unavailable',
		    504 => 'Gateway Timeout',
		    505 => 'HTTP Version Not Supported'
		);

		return (isset($codes[$status])) ? $codes[$status] : '';
	}
}

class RestRequest
{
	private $request_vars;
	private $data;
	private $http_accept;
	private $method;

	public function __construct()
	{
		$this->request_vars		= array();
		$this->data				= '';
		$this->http_accept		= (strpos($_SERVER['HTTP_ACCEPT'], 'json')) ? 'json' : 'xml';
		$this->method			= 'get';
	}

	public function setData($data)
	{
		$this->data = $data;
	}

	public function setMethod($method)
	{
		$this->method = $method;
	}

	public function setRequestVars($request_vars)
	{
		$this->request_vars = $request_vars;
	}

	public function getData()
	{
		return $this->data;
	}

	public function getMethod()
	{
		return $this->method;
	}

	public function getHttpAccept()
	{
		return $this->http_accept;
	}

	public function getRequestVars()
	{
		return $this->request_vars;
	}
}
</pre>
<p>OK, so what we&#8217;ve got is a simple class for storing some information about our request (RestRequest), and a class with some static functions we can use to deal with requests and responses.  As you can see, we really only have two functions to write&#8230; which is the beauty of this whole thing!  Right, let&#8217;s move on&#8230;</p>
<h2>Processing the Request</h2>
<p>Processing the request is pretty straight-forward, but this is where we can run into a few catches (namely with PUT and DELETE&#8230; mostly PUT).  We&#8217;ll go over those in a moment, but let&#8217;s examine the RestRequest class a bit.  If you&#8217;ll look at the constructor, you&#8217;ll see that we&#8217;re already interpreting the HTTP_ACCEPT header, and defaulting to JSON if none is provided.  With that out of the way, we need only deal with the incoming data.</p>
<p>There are a few ways we could go about doing this, but let&#8217;s just assume that we&#8217;ll always get a key/value pair in our request: &#8216;data&#8217; => actual data.  Let&#8217;s also assume that the actual data will be JSON.  As stated in my previous explanation of REST, you could look at the content-type of the request and deal with either JSON or XML, but let&#8217;s keep it simple for now.  So, our process request function will end up looking something like this:</p>
<pre name="code" class="php">
	public static function processRequest()
	{
		// get our verb
		$request_method = strtolower($_SERVER['REQUEST_METHOD']);
		$return_obj		= new RestRequest();
		// we'll store our data here
		$data			= array();

		switch ($request_method)
		{
			// gets are easy...
			case 'get':
				$data = $_GET;
				break;
			// so are posts
			case 'post':
				$data = $_POST;
				break;
			// here's the tricky bit...
			case 'put':
				// basically, we read a string from PHP's special input location,
				// and then parse it out into an array via parse_str... per the PHP docs:
				// Parses str  as if it were the query string passed via a URL and sets
				// variables in the current scope.
				parse_str(file_get_contents('php://input'), $put_vars);
				$data = $put_vars;
				break;
		}

		// store the method
		$return_obj->setMethod($request_method);

		// set the raw data, so we can access it if needed (there may be
		// other pieces to your requests)
		$return_obj->setRequestVars($data);

		if(isset($data['data']))
		{
			// translate the JSON to an Object for use however you want
			$return_obj->setData(json_decode($data['data']));
		}
		return $return_obj;
	}
</pre>
<p>Like I said, pretty straight-forward.  However, a few things to note&#8230;  First, you typically don&#8217;t accept data for DELETE requests, so we don&#8217;t have a case for them in the switch.  Second, you&#8217;ll notice that we store both the request variables, and the parsed JSON data.  This is useful as you may have other stuff as a part of your request (say an API key or something) that isn&#8217;t truly the data itself (like a new user&#8217;s name, email, etc.).</p>
<p>So, how would we use this?  Let&#8217;s go back to the user example.  Assuming you&#8217;ve routed your request to the correct controller for users, we could have some code like this:</p>
<pre name="code" class="php">
$data = RestUtils::processRequest();

switch($data->getMethod)
{
	case 'get':
		// retrieve a list of users
		break;
	case 'post':
		$user = new User();
		$user->setFirstName($data->getData()->first_name);  // just for example, this should be done cleaner
		// and so on...
		$user->save();
		break;
	// etc, etc, etc...
}
</pre>
<p>Please don&#8217;t do this in a real app, this is just a quick-and-dirty example.  You&#8217;d want to wrap this up in a nice control structure with everything abstracted properly, but this should help you get an idea of how to use this stuff.  But I digress, let&#8217;s move on to sending a response.</p>
<h2>Sending the Response</h2>
<p>Now that we can interpret the request, let&#8217;s move on to sending the response.  We already know that all we really need to do is send the correct status code, and maybe some body (if this were a GET request, for example), but there is an important catch to responses that have no body.  Say somebody made a request against our sample user API for a user that doesn&#8217;t exist (i.e. api/user/123).  The appropriate status code to send is a 404 in this case, but simply sending the status code in the headers isn&#8217;t enough.  If you viewed that page in your web browser, you would get a blank screen.  This is because Apache (or whatever your web server runs on) isn&#8217;t sending the status code, so there&#8217;s no status page.  We&#8217;ll need to take this into account when we build out our function.  Keeping all that in mind, here&#8217;s what the code should look like:</p>
<pre name="code" class="php">
	public static function sendResponse($status = 200, $body = '', $content_type = 'text/html')
	{
		$status_header = 'HTTP/1.1 ' . $status . ' ' . RestUtils::getStatusCodeMessage($status);
		// set the status
		header($status_header);
		// set the content type
		header('Content-type: ' . $content_type);

		// pages with body are easy
		if($body != '')
		{
			// send the body
			echo $body;
			exit;
		}
		// we need to create the body if none is passed
		else
		{
			// create some body messages
			$message = '';

			// this is purely optional, but makes the pages a little nicer to read
			// for your users.  Since you won't likely send a lot of different status codes,
			// this also shouldn't be too ponderous to maintain
			switch($status)
			{
				case 401:
					$message = 'You must be authorized to view this page.';
					break;
				case 404:
					$message = 'The requested URL ' . $_SERVER['REQUEST_URI'] . ' was not found.';
					break;
				case 500:
					$message = 'The server encountered an error processing your request.';
					break;
				case 501:
					$message = 'The requested method is not implemented.';
					break;
			}

			// servers don't always have a signature turned on (this is an apache directive &quot;ServerSignature On&quot;)
			$signature = ($_SERVER['SERVER_SIGNATURE'] == '') ? $_SERVER['SERVER_SOFTWARE'] . ' Server at ' . $_SERVER['SERVER_NAME'] . ' Port ' . $_SERVER['SERVER_PORT'] : $_SERVER['SERVER_SIGNATURE'];

			// this should be templatized in a real-world solution
			$body = '&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.01//EN&quot; &quot;http://www.w3.org/TR/html4/strict.dtd&quot;>
						&lt;html>
							&lt;head>
								&lt;meta http-equiv=&quot;Content-Type&quot; content=&quot;text/html; charset=iso-8859-1&quot;>
								&lt;title>' . $status . ' ' . RestUtils::getStatusCodeMessage($status) . '&lt;/title>
							&lt;/head>
							&lt;body>
								&lt;h1>' . RestUtils::getStatusCodeMessage($status) . '&lt;/h1>
								&lt;p>' . $message . '&lt;/p>
								&lt;hr />
								&lt;address>' . $signature . '&lt;/address>
							&lt;/body>
						&lt;/html>';

			echo $body;
			exit;
		}
	}
</pre>
<p>That&#8217;s It!  We technically have everything we need now to process requests and send responses.  Let&#8217;s talk a bit more about why we need to have a standard body response or a custom one.  For GET requests, this is pretty obvious, we need to send XML / JSON content instead of a status page (provided the request was valid).  However, there&#8217;s also POSTs to deal with.  Inside of your apps, when you create a new entity, you probably fetch the new entity&#8217;s ID via something like mysql_insert_id().  Well, if a user posts to your API, they&#8217;ll probably want that new ID as well.  What I&#8217;ll usually do in this case is simply send the new ID as the body (with a 201 status code), but you could also wrap that in XML or JSON if you&#8217;d like.</p>
<p>So, let&#8217;s extend our sample implementation a bit:</p>
<pre name="code" class="php">
switch($data->getMethod)
{
	// this is a request for all users, not one in particular
	case 'get':
		$user_list = getUserList(); // assume this returns an array

		if($data->getHttpAccept == 'json')
		{
			RestUtils::sendResponse(200, json_encode($user_list), 'application/json');
		}
		else if ($data->getHttpAccept == 'xml')
		{
			// using the XML_SERIALIZER Pear Package
			$options = array
			(
				'indent' => '     ',
				'addDecl' => false,
				'rootName' => $fc->getAction(),
				XML_SERIALIZER_OPTION_RETURN_RESULT => true
			);
			$serializer = new XML_Serializer($options);

			RestUtils::sendResponse(200, $serializer->serialize($user_list), 'application/xml');
		}

		break;
	// new user create
	case 'post':
		$user = new User();
		$user->setFirstName($data->getData()->first_name);  // just for example, this should be done cleaner
		// and so on...
		$user->save();

		// just send the new ID as the body
		RestUtils::sendResponse(201, $user->getId());
		break;
}
</pre>
<p>Again, this is just an example, but it does show off (I think, at least) how little effort it takes to implement RESTful stuff.</p>
<h2>Wrapping Up</h2>
<p>So, that&#8217;s about it.  I&#8217;m pretty confident that I&#8217;ve beaten the point that this should be quite easy into the ground, so I&#8217;d like to close with how you can take this stuff further and perhaps properly implement it.</p>
<p>In a real-world MVC application, what you would probably want to do is set up a controller for your API that loads individual API controllers.  For example, using the above stuff, we&#8217;d possibly create a UserRestController which had four methods: get(), put(), post(), and delete().  The API controller would look at the request and determine which method to invoke on that controller.  That method would then use the utils to process the request, do what it needs to do data-wise, then use the utils to send a response.</p>
<p>You could also take it a step further than that, and abstract out your API controller and data models a bit more.  Rather than explicitly creating a controller for every data model in your app, you could add some logic into your API controller to first look for an explicitly defined controller, and if none is found, try to look for an existing model.  For example, the url &#8220;api/user/1&#8243;, would first trigger a lookup for a &#8220;user&#8221; rest controller.  If none is found, it could then look for a model called &#8220;user&#8221; in your app.  If one is found, you could write up a bit of automated voodoo to automatically process all the requests against those models.</p>
<p>Going even further, you could then make a generic &#8220;list-all&#8221; method that works similar to the previous paragraph&#8217;s example.  Say your url was &#8220;api/users&#8221;.  The API controller could first check for a &#8220;users&#8221; rest controller, and if none was found, recognize that users is pluaralized, depluralize it, and then look for a &#8220;user&#8221; model.  If one&#8217;s found, load a list the list of users and send that off.</p>
<p>Finally, you could add digest authentication to your API quite easily as well.  Say you only wanted properly authenticated users to access your API, well, you could throw some code like this into your process request functionality (borrowed from an existing app of mine, so there&#8217;s some constants and variables referenced that aren&#8217;t defined in this snippet):</p>
<pre name="code" class="php">
			// figure out if we need to challenge the user
			if(empty($_SERVER['PHP_AUTH_DIGEST']))
			{
				header('HTTP/1.1 401 Unauthorized');
				header('WWW-Authenticate: Digest realm="' . AUTH_REALM . '",qop="auth",nonce="' . uniqid() . '",opaque="' . md5(AUTH_REALM) . '"');

				// show the error if they hit cancel
				die(RestControllerLib::error(401, true));
			}

			// now, analayze the PHP_AUTH_DIGEST var
			if(!($data = http_digest_parse($_SERVER['PHP_AUTH_DIGEST'])) || $auth_username != $data['username'])
			{
				// show the error due to bad auth
				die(RestUtils::sendResponse(401));
			}

			// so far, everything's good, let's now check the response a bit more...
			$A1 = md5($data['username'] . ':' . AUTH_REALM . ':' . $auth_pass);
			$A2 = md5($_SERVER['REQUEST_METHOD'] . ':' . $data['uri']);
			$valid_response = md5($A1 . ':' . $data['nonce'] . ':' . $data['nc'] . ':' . $data['cnonce'] . ':' . $data['qop'] . ':' . $A2);

			// last check..
			if($data['response'] != $valid_response)
			{
				die(RestUtils::sendResponse(401));
			}
</pre>
<p>Pretty cool stuff, huh?  With a little bit of code and some clever logic, you can add a fully functional REST API to your apps very quickly.  I&#8217;m not just saying that to cheerlead the concept either, I implemented this stuff into one of my personal frameworks in about half a day, and then spent another half day adding all sorts of cool magic to it.  If you (the reader) are interested in seeing my final implementation, drop me a note in the comments and I&#8217;d be happy to share it with you!  Also, if you&#8217;ve got any cool ideas you&#8217;d like to share, be sure to drop those in the comments as well&#8230; if I like it enough, I&#8217;d even let you guest author your own article on the subject!</p>
<p>Until next time&#8230;</p>
<p><strong>UPDATE:</strong>  The much-requested follow-up to this article has been posted: <a href="http://www.gen-x-design.com/archives/making-restful-requests-in-php/">Making RESTful Requests in PHP</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.gen-x-design.com/archives/create-a-rest-api-with-php/feed/</wfw:commentRss>
		<slash:comments>79</slash:comments>
		</item>
	</channel>
</rss>
