REST – Can You do More than Spell It? Part 3
Part 1 of this series dealt with REST from a theoretical perspective, specifically, what the heck is it. And then, part 2 dove deeper, talking about how you might go about building a REST-oriented system. It’s certainly been an exciting journey of self-realization thus far, but there’s no time to rest, if you will. We must keep going!
Imagine it’s a warm, sunny, summer day. You’re just walking along, taking a leisurely noonday stroll, when all of a sudden you come face to face with a RESTful API. What do you do? How do you interface with it? Or, as those of us in the know would say, “how do you consume RESTful services?” That, my friends, is the subject of this article.
Interacting with REST
There are essentially three basic things that need to be done within your PHP program to consume REST services over HTTP: specifying the URL for the resource to be accessed (either used or created), specifying any parameters needed to accompany the request, and finally invoking the correct HTTP verb to do the actual retrieving or updating/creating.
First, you need to determine the URL that you want to create, get, update, or delete. Remember, every REST resource is identified by a unique URL, so that choosing the correct URL to use is very important. Sometimes the pieces that make up the URL will be strictly defined by the API, and other times the API will accept anything, no matter how long or obtuse. In such cases where you define the URL yourself, you should make an effort to make it as short and yet meaningful as possible. URLs should be human readable.
Second, you need to think about the data that you will use in the transaction. That is, any web interaction is going to involve moving data to or from applications and so setting up the data that you are going to transfer is pretty important. There are a number of ways in which this can be done; you could provide the data as
POST parameters, HTTP headers, or even an XML or JSON payload.
And now, the final step; talking to the REST service. As you might guess, there are a number of ways to do this. If you are using a framework like Zend Framework or WS02 then you’ll most likely have REST/HTTP convenience functions made available to you by it. If you are not using a framework, then there are two PHP extensions in particular you’ll find helpful. The first (and the one I’ll use here) is cURL, a wrapper around the libcurl library. The second is the pecl_http extension, which can easily be downloaded and installed via PECL. Either one should work nicely for you, allowing you to write PHP code that can easily work with HTTP content and headers.
I should probably also mention that that you don’t need to use cURL or PECL; of course you can do everything with straight-up PHP function (like
file_put_contents()), but it’s a bit more wordy and not quite as elegant. For an example of using such PHP functions to communicate with remote a remote server, see Dustin Runnell’s article Understanding OAuth – Tweeting from Scratch.
Bringing It Together
There are four steps to every cURL activity:
- Initialize a cURL resource
- Set any necessary cURL options
- Execute the HTTP call
- Parse the returned response
So without further ado, let’s bring the three main steps (and 4 curl-specific steps) together with an example:
<?php // set up the URL value involved in a variable $url = "http://www.funland.com/summerschedule"; // set up the data that is going to be passed $events = array( array("event" => "20120601-0001", "name" => "AC/DC Drink Till U Drop Concert", "date" => "20120601", "time" => "22000030"), array("event" => "20120602-0001", "name" => "Enya – Can You Feel the Peace", "date" => "20120602", "time" => "19300045"), array("event" => "20120603-0002", "name" => "Nicki Menaj – The Midnight Girls Concerrtt", "date" => "20120603", "time" => "21300039")); $jsonData = json_encode($events) // perform the curl transaction $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, $jsonData); $response = curl_exec($ch); $decode = json_decode($response); print_r($resonse);
The example specifies the target resource that will be called, and a JSON payload with event information. Then a cURL handle is initialized using the
curl_init() function. The handle is used with subsequent cURL functions related to this call.
Then a few cURL options are set to tell cURL what it is exactly that you want it to do. This is done through the
CURLOPT_URL– lets cURL know the URL you want to operate on, in this case using the
$urlvariable that was defined previously.
CURLOPT_RETURNTRANSFER– tells cURL not to send the response directly to browser but to return it as a string from
CURLOPT_POST– identifies what HTTP verb to use, in this case
POST. Note that the value
trueis required as the third parameter here or else the statement will not work.
cURL is a very flexible library and there is a plethora of configurable options you can specify. For a complete list, be sure to check out the cURL documentation on the PHP site.
Then it’s time to actually execute the cURL call and interpret the results. As written above, the data that is entered into JSON via the
json_encode() function will be passed on to cURL using the
$jsonData variable. If you were doing a
GET, then the logic would be similar except
CURLOPT_GET would be used and you would follow up the cURL commands with the
json_decode() function that would take the JSON data returned and move it into a PHP array.
This article presented a very simple outline of how to do an HTTP connection from your PHP scripts. Now the only remaining question is – how does this model qualify as RESTful and how do you keep it that way? Keep in mind that since REST is a state of mind, rather than a standard, there can be a certain amount of debate as to whether a specific system is RESTful or not. But let’s go back to our basic principles.
REST treats everything as a resource and assigns a URL to that resource. And we got to do that with the first line of code. The URL in addition forms a meaningful name, is in direct opposition to an RPC architecture where everything goes to an action node and not necessarily the final destination.
REST is stateless, and as noted from the example, there is nothing in there that carries information about previous or future transactions. Each one is independent of what happened before (except for normal data dependencies).
REST is about simplicity, and yet is robust and powerful. The example used a standard protocol (HTTP) and the cURL extension. Nothing special needs to be loaded, just the basic capabilities of PHP and HTTP.
And speaking of HTTP, there is one more thing that needs to be explored; something that we hinted about with the
print_r() statement above; response codes and HTTP headers. If you are going to do a POST or other operations that are carried out on the server, then you need to have some idea as to whether or not it worked. Similarly, you may also want to give the server some directions on how to do the POST or what type of data to pick up with a GET. All of this and more (well, mostly “all of this”) will be covered in the final chapter of the saga where I’ll introduce you to the fascinating world of HTTP headers.