1. What is REST?

REST stands for Representational State Transfer. (It is sometimes spelled "ReST".) It relies on a stateless, client-server, cacheable communications protocol -- and in virtually all cases, the HTTP protocol is used.

REST is an architecture style for designing networked applications. The idea is that, rather than using complex mechanisms such as CORBA, RPC or SOAP to connect between machines, simple HTTP is used to make calls between machines.

  • In many ways, the World Wide Web itself, based on HTTP, can be viewed as a REST-based architecture.

RESTful applications use HTTP requests to post data (create and/or update), read data (e.g., make queries), and delete data. Thus, REST uses HTTP for all four CRUD (Create/Read/Update/Delete) operations.

REST is a lightweight alternative to mechanisms like RPC (Remote Procedure Calls) and Web Services (SOAP, WSDL, et al.). Later, we will see how much more simple REST is.

  • Despite being simple, REST is fully-featured; there's basically nothing you can do in Web Services that can't be done with a RESTful architecture.

REST is not a "standard". There will never be a W3C recommendataion for REST, for example. And while there are REST programming frameworks, working with REST is so simple that you can often "roll your own" with standard library features in languages like Perl, Java, or C#.

2. REST as Lightweight Web Services

As a programming approach, REST is a lightweight alternative to Web Services and RPC.

Much like Web Services, a REST service is:

  • Platform-independent (you don't care if the server is Unix, the client is a Mac, or anything else),
  • Language-independent (C# can talk to Java, etc.),
  • Standards-based (runs on top of HTTP), and
  • Can easily be used in the presence of firewalls.

Like Web Services, REST offers no built-in security features, encryption, session management, QoS guarantees, etc. But also as with Web Services, these can be added by building on top of HTTP:

  • For security, username/password tokens are often used.
  • For encryption, REST can be used on top of HTTPS (secure sockets).
  • ... etc.

One thing that is not part of a good REST design is cookies: The "ST" in "REST" stands for "State Transfer", and indeed, in a good REST design operations are self-contained, and each request carries with it (transfers) all the information (state) that the server needs in order to complete it.

3. How Simple is REST?

Let's take a simple web service as an example: querying a phonebook application for the details of a given user. All we have is the user's ID.

Using Web Services and SOAP, the request would look something like this:

<?xml version="1.0"?>
<soap:Envelope
xmlns:soap="http://www.w3.org/2001/12/soap-envelope"
soap:encodingStyle="http://www.w3.org/2001/12/soap-encoding">
 <soap:body pb="http://www.acme.com/phonebook">
  <pb:GetUserDetails>
   <pb:UserID>12345</pb:UserID>
  </pb:GetUserDetails>
 </soap:Body>
</soap:Envelope>

(The details are not important; this is just an example.) The entire shebang now has to be sent (using an HTTP POST request) to the server. The result is probably an XML file, but it will be embedded, as the "payload", inside a SOAP response envelope.

And with REST? The query will probably look like this:

http://www.acme.com/phonebook/UserDetails/12345

Note that this isn't the request body -- it's just a URL. This URL is sent to the server using a simpler GET request, and the HTTP reply is the raw result data -- not embedded inside anything, just the data you need in a way you can directly use.

  • It's easy to see why Web Services are often used with libraries that create the SOAP/HTTP request and send it over, and then parse the SOAP response.
  • With REST, a simple network connection is all you need. You can even test the API directly, using your browser.
  • Still, REST libraries (for simplifying things) do exist, and we will discuss some of these later.

Note how the URL's "method" part is not called "GetUserDetails", but simply "UserDetails". It is a common convention in REST design to use nouns rather than verbs to denote simple resources.

The letter analogy
A nice analogy for REST vs. SOAP is mailing a letter: with SOAP, you're using an envelope; with REST, it's a postcard. Postcards are easier to handle (by the receiver), waste less paper (i.e., consume less bandwidth), and have a short content. (Of course, REST requests aren't really limited in length, esp. if they use POST rather than GET.)

But don't carry the analogy too far: unlike letters-vs.-postcards, REST is every bit as secure as SOAP. In particular, REST can be carried over secure sockets (using the HTTPS protocol), and content can be encrypted using any mechanism you see fit. Without encryption, REST and SOAP are both insecure; with proper encryption in place, both are equally secure.

4. More Complex REST Requests

The previous section included a simple example for a REST request -- with a single parameter.

REST can easily handle more complex requests, including multiple parameters. In most cases, you'll just use HTTP GET parameters in the URL.

For example:

http://www.acme.com/phonebook/UserDetails?firstName=John&lastName=Doe

If you need to pass long parameters, or binary ones, you'd normally use HTTP POST requests, and include the parameters in the POST body.

As a rule, GET requests should be for read-only queries; they should not change the state of the server and its data. For creation, updating, and deleting data, use POST requests. (POST can also be used for read-only queries, as noted above, when complex parameters are required.)

  • In a way, this web page (like most others) can be viewed as offering services via a REST API; you use a GET request to read data, and a POST request to post a comment -- where more and longer parameters are required.

While REST services might use XML in their responses (as one way of organizing structured data), REST requests rarely use XML. As shown above, in most cases, request parameters are simple, and there is no need for the overhead of XML.

  • One advantage of using XML is type safety. However, in a stateless system like REST, you should always verify the validity of your input, XML or otherwise!

5. REST Server Responses

A server response in REST is often an XML file; for example,

<parts-list>
 <part id="3322">
  <name>ACME Boomerang</name>
  <desc>
   Used by Coyote in <i>Zoom at the Top</i>, 1962
  </desc>
  <price currency="usd" quantity="1">17.32</price>
  <uri>http://www.acme.com/parts/3322</uri>
 </part>
 <part id="783">
  <name>ACME Dehydrated Boulders</name>
  <desc>
   Used by Coyote in <i>Scrambled Aches</i>, 1957
  </desc>
  <price currency="usd" quantity="pack">19.95</price>
  <uri>http://www.acme.com/parts/783</uri>
 </part>
</parts-list>

However, other formats can also be used; unlike SOAP services, REST is not bound to XML in any way. Possible formats include CSV (comma-separated values) and JSON (JavaScript Object Notation).

Each format has its own advantages and disadvantages. XML is easy to expand (clients should ignore unfamiliar fields) and is type-safe; CSV is more compact; and JSON is trivial to parse in JavaScript clients (and easy to parse in other languages, too).

One option is not acceptable as a REST response format, except in very specific cases: HTML, or any other format which is meant for human consumption and is not easily processed by clients. The specific exception is, of course, when the REST service is documented to return a human-readable document; and when viewing the entire WWW as a RESTful application, we find that HTML is in fact the most common REST response format...

6. Real REST Examples

Here's a very partial list of service providers that use a REST API. Note that some of them also support a WSDL (Web Services) API, in addition, so you can pick which to use; but in most cases, when both alternatives are available, REST calls are easier to create, the results are easier to parse and use, and it's also less resource-heavy on your system.
So without further ado, some REST services:

  • The Google Glass API, known as "Mirror API", is a pure REST API. Here is an excellent video talk about this API. (The actual API discussion starts after 16 minutes or so.)
  • Twitter has a REST API (in fact, this was their original API and, so far as I can tell, it's still the main API used by Twitter application developers),
  • Flickr,
  • Amazon.com offer several REST services, e.g., for their S3 storage solution,
  • Atom is a RESTful alternative to RSS,
  • Tesla Model S uses an (undocumented) REST API between the car systems and its Android/iOS apps.

(This is far from an exhaustive list.)

7. AJAX and REST

AJAX is a popular web development technique that makes web pages interactive using JavaScript.

In AJAX, requests are sent to the server using XMLHttpRequest objects. The response is used by the JavaScript code to dynamically change the current page.

In many ways, AJAX applications follow the REST design principles. Each XMLHttpRequest can be viewed as a REST service request, sent using GET. And the response is often in JSON, a popular response format for REST. (See REST Server Responses, above.)

To make your AJAX application truly RESTful, follow the standard REST design principles (discussed later). You will find that most of them contribute to a good design, even if you don't think of your architecture in terms of REST.

A later section provides code samples for issuing HTTP requests in JavaScript, but if you've done any AJAX programming, you are already familiar with all that.

8. REST Architecture Components

Key components of a REST architecture:

  • Resources, which are identified by logical URLs. Both state and functionality are represented using resources.
    • The logical URLs imply that the resources are universally addressable by other parts of the system.
    • Resources are the key element of a true RESTful design, as opposed to "methods" or "services" used in RPC and SOAP Web Services, respectively. You do not issue a "getProductName" and then a "getProductPrice" RPC calls in REST; rather, you view the product data as a resource -- and this resource should contain all the required information (or links to it).
  • A web of resources, meaning that a single resource should not be overwhelmingly large and contain too fine-grained details. Whenever relevant, a resource should contain links to additional information -- just as in web pages.
  • The system has a client-server, but of course one component's server can be another component's client.
  • There is no connection state; interaction is stateless (although the servers and resources can of course be stateful). Each new request should carry all the information required to complete it, and must not rely on previous interactions with the same client.
  • Resources should be cachable whenever possible (with an expiration date/time). The protocol must allow the server to explicitly specify which resources may be cached, and for how long.
    • Since HTTP is universally used as the REST protocol, the HTTP cache-control headers are used for this purpose.
    • Clients must respect the server's cache specification for each resource.
  • Proxy servers can be used as part of the architecture, to improve performance and scalability. Any standard HTTP proxy can be used.

Note that your application can use REST services (as a client) without being a REST architecture by itself; e.g., a single-machine, non-REST program can access 3rd-party REST services.

9. REST Design Guidelines

Some soft guidelines for designing a REST architecture:

  1. Do not use "physical" URLs. A physical URL points at something physical -- e.g., an XML file: "http://www.acme.com/inventory/product003.xml". A logical URL does not imply a physical file: "http://www.acme.com/inventory/product/003".
    • Sure, even with the .xml extension, the content could be dynamically generated. But it should be "humanly visible" that the URL is logical and not physical.
  2. Queries should not return an overload of data. If needed, provide a paging mechanism. For example, a "product list" GET request should return the first n products (e.g., the first 10), with next/prev links.
  3. Even though the REST response can be anything, make sure it's well documented, and do not change the output format lightly (since it will break existing clients).
    • Remember, even if the output is human-readable, your clients aren't human users.
    • If the output is in XML, make sure you document it with a schema or a DTD.
  4. Rather than letting clients construct URLs for additional actions, include the actual URLs with REST responses. For example, a "product list" request could return an ID per product, and the specification says that you should use http://www.acme.com/product/PRODUCT_ID to get additional details. That's bad design. Rather, the response should include the actual URL with each item: http://www.acme.com/product/001263, etc.
    • Yes, this means that the output is larger. But it also means that you can easily direct clients to new URLs as needed, without requiring a change in client code.
  5. GET access requests should never cause a state change. Anything that changes the server state should be a POST request (or other HTTP verbs, such as DELETE).

10. ROA vs. SOA, REST vs. SOAP

ROA (REST Oriented Architecture) is just a fancy name for a SOA (Service Based Architecture) using REST services.

The main advantage of SOAP-based SOA over ROA is the more mature tool support; however, this could change over time. Another SOA advantages include the type-safety of XML requests (for responses, ROA can also use XML if the developers desire it).

The main advantage of ROA is ease of implementation, agility of the design, and the lightweight approach to things. In a way, SOA and SOAP is for people in business suits; that's what you'll find used in the banking and finance industries. Conversely, somebody that needs something up-and-running quickly, with good performance and low overhead, is often better off using REST and ROA.

For example, when explaining why they chose REST over SOAP, Yahoo! people write that they "believe REST has a lower barrier to entry, is easier to use than SOAP, and is entirely sufficient for [Yahoo's] services" (Yahoo! Developer Network FAQ, as of February 2008). This is true not only of REST vs. SOAP but also of ROA vs. SOA in general.

Another advantage of REST lies with performance: with better cache support, lightweight requests and responses, and easier response parsing, REST allows for nimbler clients and servers, and reduces network traffic, too.

As REST matures, expect it to become better understood and more popular even in more conservative industries.

A few words on hype vs. reality. In the comments below, I've linked to Pete Lacey's excellent criticism of SOAP, "The S Stands for Simple". And here's another one, by Alex Bell, published in Communications of the ACM (vol. 51, no. 10, October '08): "DOA with SOA".

11. Documenting REST Services: WSDL and WADL

WSDL, a W3C recommendation, is the Web Services Description Language. It is commonly used to spell out in detail the services offered by a SOAP server. While WSDL is flexible in service binding options (for example, services can be offered via SMTP mail servers), it did not originally support HTTP operations other than GET and POST. Since REST services often use other HTTP verbs, such as PUT and DELETE, WSDL was a poor choice for documenting REST services.

With version 2.0, WSDL supports all HTTP verbs and it is now considered to be an acceptable method of documenting REST services.

The second alternative is WADL, the Web Application Description Language. WADL is championed by Sun Microsystems. Like the rest of REST, WADL is lightweight, easier to understand and easier to write than WSDL. In some respects, it is not as flexible as WSDL (no binding to SMTP servers), but it is sufficient for any REST service and much less verbose.

Here is a fragment from a WADL specification, describing Amazon's "Item Search" service:

<method name="GET" id="ItemSearch">
 <request>
  <param name="Service" style="query"
   fixed="AWSECommerceService"/>
  <param name="Version" style="query" fixed="2005-07-26"/>
  <param name="Operation" style="query" fixed="ItemSearch"/>
  <param name="SubscriptionId" style="query"
   type="xsd:string" required="true"/>
  <param name="SearchIndex" style="query"
   type="aws:SearchIndexType" required="true">
    <option value="Books"/>
    <option value="DVD"/>
    <option value="Music"/>
  </param>
  <param name="Keywords" style="query"
   type="aws:KeywordList" required="true"/>
  <param name="ResponseGroup" style="query"
   type="aws:ResponseGroupType" repeating="true">
    <option value="Small"/>
    <option value="Medium"/>
    <option value="Large"/>
    <option value="Images"/>
  </param>
 </request>
 <response>
  <representation mediaType="text/xml"
   element="aws:ItemSearchResponse"/>
 </response>
</method>

As you can see, for format is mostly self-explanatory, and it enriches REST with such goodies as type safety using XML schema types.

Some REST advocates, however, find even the lightweight WADL to be an overkill. And indeed, most REST services are documented by no more than a textual description (a human-readable HTML file).

12. REST Examples in Different Languages

The following sections provide brief examples for accessing REST services in different programming languages. More than anything else, they present mechanisms for sending HTTP GET and/or POST requests in each language; the rest of using REST is simply a matter of architectural design.

You might wish to skip directly to your language of choice (the list is alphabetical):

Finally, the tutorial conclusion contains references to additional resources.

12.1. Using REST in C#

Issuing HTTP GET Requests
The key classes here are HttpWebRequest and HttpWebResponse from System.Net.

The following method issues a request and returns the entire response as one long string:

static string HttpGet(string url) {
  HttpWebRequest req = WebRequest.Create(url)
                       as HttpWebRequest;
  string result = null;
  using (HttpWebResponse resp = req.GetResponse()
                                as HttpWebResponse)
  {
    StreamReader reader =
        new StreamReader(resp.GetResponseStream());
    result = reader.ReadToEnd();
  }
  return result;
}

Remember that if the request URL includes parameters, they must be properly encoded (e.g., a space is %20, etc.). The System.Web namespace has a class called HttpUtility, with a static method called UrlEncode for just such encoding.

Issuing HTTP POST Requests
URL encoding is also required for POST requests -- in addition to form encoding, as shown in the following method:

static string HttpPost(string url, 
    string[] paramName, string[] paramVal)
{
  HttpWebRequest req = WebRequest.Create(new Uri(url)) 
                       as HttpWebRequest;
  req.Method = "POST";  
  req.ContentType = "application/x-www-form-urlencoded";

  // Build a string with all the params, properly encoded.
  // We assume that the arrays paramName and paramVal are
  // of equal length:
  StringBuilder paramz = new StringBuilder();
  for (int i = 0; i < paramName.Length; i++) {
    paramz.Append(paramName[i]);
    paramz.Append("=");
    paramz.Append(HttpUtility.UrlEncode(paramVal[i]));
    paramz.Append("&");
  }

  // Encode the parameters as form data:
  byte[] formData =
      UTF8Encoding.UTF8.GetBytes(paramz.ToString());
  req.ContentLength = formData.Length;

  // Send the request:
  using (Stream post = req.GetRequestStream())  
  {  
    post.Write(formData, 0, formData.Length);  
  }

  // Pick up the response:
  string result = null;
  using (HttpWebResponse resp = req.GetResponse()
                                as HttpWebResponse)  
  {  
    StreamReader reader = 
        new StreamReader(resp.GetResponseStream());
    result = reader.ReadToEnd();
  }

  return result;
}

For more examples, see this page on the Yahoo! Developers Network.

12.2. Using REST in Java

Issuing HTTP GET Requests
The key class here is HttpURLConnection, obtained by invoking openConnection on a URL object. Sadly, openConnection method's signature specifies that it returns the superclass type, URLConnection, and we have to downcast the result.

The following method issues a request and returns the entire response as one long string:

public static String httpGet(String urlStr) throws IOException {
  URL url = new URL(urlStr);
  HttpURLConnection conn =
      (HttpURLConnection) url.openConnection();

  if (conn.getResponseCode() != 200) {
    throw new IOException(conn.getResponseMessage());
  }

  // Buffer the result into a string
  BufferedReader rd = new BufferedReader(
      new InputStreamReader(conn.getInputStream()));
  StringBuilder sb = new StringBuilder();
  String line;
  while ((line = rd.readLine()) != null) {
    sb.append(line);
  }
  rd.close();

  conn.disconnect();
  return sb.toString();
}

(This code is very raw; it should be properly padded with try/catch/finally blocks to ensure the reader is closed, etc.)

Remember that if the request URL includes parameters, they must be properly encoded (e.g., a space is %20, etc.). The class URLEncoder can be used to perform this encoding.

Issuing HTTP POST Requests
URL encoding is also required for POST requests, as shown in the following method:

public static String httpPost(String urlStr, String[] paramName,
String[] paramVal) throws Exception {
  URL url = new URL(urlStr);
  HttpURLConnection conn =
      (HttpURLConnection) url.openConnection();
  conn.setRequestMethod("POST");
  conn.setDoOutput(true);
  conn.setDoInput(true);
  conn.setUseCaches(false);
  conn.setAllowUserInteraction(false);
  conn.setRequestProperty("Content-Type",
      "application/x-www-form-urlencoded");

  // Create the form content
  OutputStream out = conn.getOutputStream();
  Writer writer = new OutputStreamWriter(out, "UTF-8");
  for (int i = 0; i < paramName.length; i++) {
    writer.write(paramName[i]);
    writer.write("=");
    writer.write(URLEncoder.encode(paramVal[i], "UTF-8"));
    writer.write("&");
  }
  writer.close();
  out.close();

  if (conn.getResponseCode() != 200) {
    throw new IOException(conn.getResponseMessage());
  }

  // Buffer the result into a string
  BufferedReader rd = new BufferedReader(
      new InputStreamReader(conn.getInputStream()));
  StringBuilder sb = new StringBuilder();
  String line;
  while ((line = rd.readLine()) != null) {
    sb.append(line);
  }
  rd.close();

  conn.disconnect();
  return sb.toString();
}

As you can see, it's not a pretty sight (and that's before adding proper try/catch/finally structures). The problem is that, out of the box, Java's support for handling web connections is pretty low-level.

A good solution can be found in the popular Apache Commons library, and in particular the httpclient set of packages. See Yahoo! guide to REST with Java for details and examples. The documentation covers several interesting extras, such as caching.

12.3. Using REST in JavaScript

The page discusses sending REST requests from client-side (in-browser) JavaScript. If you're using server-side JavaScript, see your server vendor's documentation for creating HTTP requests.

If you have developed AJAX applications, all this will seem trivial to you: after all, every AJAX request is an HTTP request, and in many ways, AJAX applications are RESTful.

Creating XMLHttpRequest Objects
Sending HTTP requests in JavaScript involves the XMLHttpRequest object. Note that despite its name, neither the request nor the response has to involve XML.

Sadly, there is no standard way to create XMLHttpRequest objects. The following function is a cross-browser solution:

function createRequest() {
  var result = null;
  if (window.XMLHttpRequest) {
    // FireFox, Safari, etc.
    result = new XMLHttpRequest();
    if (typeof xmlhttp.overrideMimeType != 'undefined') {
      result.overrideMimeType('text/xml'); // Or anything else
    }
  }
  else if (window.ActiveXObject) {
    // MSIE
    result = new ActiveXObject("Microsoft.XMLHTTP");
  } 
  else {
    // No known mechanism -- consider aborting the application
  }
  return result;
}

Using XMLHttpRequest
An XMLHttpRequest object allows you to send a request, either GET or POST; however, it does not immediately return a value. Rather, you have to supply a callback function that will be invoked when the request completes. Confusingly, you callback is actually invoked several times (up to four times, depending on the browser), during different stages of the client/server interaction. It is only the fourth and final stage that interests us; the readyState field can be used to test for the stage, as shown in the following code fragment:

var req = createRequest(); // defined above
// Create the callback:
req.onreadystatechange = function() {
  if (req.readyState != 4) return; // Not there yet
  if (req.status != 200) {
    // Handle request failure here...
    return;
  }
  // Request successful, read the response
  var resp = req.responseText;
  // ... and use it as needed by your app.
}

Note that if the response is an XML response (denoted by the server using MIME type text/xml), it can also be read using the responseXML property. This property contains an XML document, and can be used as such using JavaScript's DOM navigation facilities.

Sending the Request
Once we have created the request object and set up its callback function, it is time to issue the request:

req.open("GET", url, true);
req.send();

For POST requests, use:

req.open("POST", url, true);
req.setRequestHeader("Content-Type",
                     "application/x-www-form-urlencoded");
req.send(form-encoded request body);

For more information about sending HTTP requests from JavaScript, just google for XMLHttpRequest.

12.4. Using REST in Perl

To work with HTTP in Perl, we will use LWP -- the Library for WWW in Perl.

Issuing GET Requests
GET requests are pretty trivial with LWP, especially if you don't care much about setting headers in the request or reading headers in the response:

use LWP::Simple;

my $url = 'http://www.acme.com/products/3322';
          # ACME boomerang
my $response = get $url;
die 'Error getting $url' unless defined $response;

For more advanced features, you'll need to create a browser object, thus:

use LWP;
my $browser = LWP::UserAgent->new;
my $url = 'http://www.acme.com/products/3322';

# Issue request, with an HTTP header
my $response = $browser->get($url,
  'User-Agent' => 'Mozilla/4.0 (compatible; MSIE 7.0)',
);
die 'Error getting $url' unless $response->is_success;
print 'Content type is ', $response->content_type;
print 'Content is:';
print $response->content;

Issuing POST Requests
The same browser object defined above can be used to issue POST requests, too. Field names are directly mapped to values, thus:

my $response = $browser->post($url,
  [
   'firstName' => 'John',
   'lastName' => 'Doe'
  ],
);
die 'Error getting $url' unless $response->is_success;

Note that the UserAgent class allows you to easily set and read cookies, too, but these should be avoided in REST designs.

Additional information about using LWP for web requests can be found in the article Web Basics with LWP, by Sean M. Burke, author of Perl & LWP.

12.5. Using REST in PHP

Issuing GET Requests
Modern versions of PHP make it trivial to GET web pages: any file-access function (even include!) works seamlessly with URLs, too. Thus, you can use fopen, file_get_contents, and any other file-reading function to issue GET requests. For example:

$url = "http://www.acme.com/products/3322";
$response = file_get_contents($url);
echo $response;

Any parameters passed to GET requests must be encoded (e.g., a space is %20); you can encode strings using the urlencode function.

Issuing POST Requests
In stark contrast to the ease of doing a GET, there's no simple way to do a POST in PHP. You have to open a connection to the server and manually send all HTTP headers. Here's a simple function that will do the trick, for any HTTP method:

function httpRequest($host, $port, $method, $path, $params) {
  // Params are a map from names to values
  $paramStr = "";
  foreach ($params as $name, $val) {
    $paramStr .= $name . "=";
    $paramStr .= urlencode($val);
    $paramStr .= "&";
  }

  // Assign defaults to $method and $port, if needed
  if (empty($method)) {
    $method = 'GET';
  }
  $method = strtoupper($method);
  if (empty($port)) {
    $port = 80; // Default HTTP port
  }

  // Create the connection
  $sock = fsockopen($host, $port);
  if ($method == "GET") {
    $path .= "?" . $paramStr;
  }
  fputs($sock, "$method $path HTTP/1.1\r\n");
  fputs($sock, "Host: $host\r\n");
  fputs($sock, "Content-type: " .
               "application/x-www-form-urlencoded\r\n");
  if ($method == "POST") {
    fputs($sock, "Content-length: " . 
                 strlen($paramStr) . "\r\n");
  }
  fputs($sock, "Connection: close\r\n\r\n");
  if ($method == "POST") {
    fputs($sock, $paramStr);
  }

  // Buffer the result
  $result = "";
  while (!feof($sock)) {
    $result .= fgets($sock,1024);
  }

  fclose($sock);
  return $result;
}

Issuing a POST request using this function is as simple as:

$resp = httpRequest("www.acme.com",
    80, "POST", "/userDetails",
    array("firstName" => "John", "lastName" => "Doe"));

One alternative to this approach is using PHP's CURL support; however, I'm not sure if it's really easier.

12.6. Using REST in Python

Issuing GET Requests
The Python module urllib2 makes reading URLs trivial:

import urllib2

url = 'http://www.acme.com/products/3322'
response = urllib2.urlopen(url).read()

Errors are reported as exceptions (urllib2.HTTPError or urllib2.URLError).

Issuing POST Requests
A POST request is just as easy, simply passing (encoded) request data as an extra parameter to urlopen, thus:

import urllib
import urllib2

url = 'http://www.acme.com/users/details'
params = urllib.urlencode({
  'firstName': 'John',
  'lastName': 'Doe'
})
response = urllib2.urlopen(url, params).read()

Note that encoding is done using a function from the urllib module.

12.7. Using REST in Ruby

As with Python, sending HTTP requests in Ruby is extremely easy.

Issuing GET Requests
We use the class Net::HTTP to do all the magic:

require 'net/http'

url = 'http://www.acme.com/products/3322' # ACME boomerang
resp = Net::HTTP.get_response(URI.parse(url))

resp_text = resp.body

The response field code contains the HTTP response code. To make things simpler, the result object's very class indicates the response type; for example, resp (in the example above) will be of type Net::HTTPSuccess if the response is 2xx (HTTP OK code), or Net::HTTPNotFound for 404 responoses (HTTP Not Found code). A complete hierarchy of the response classes appears in Net::HTTP's documentation.

Issuing POST Requests
We need Net::HTTP's post_form method for POSTing:

require 'net/http'

url = 'http://www.acme.com/user/details'
params = {
  firstName => 'John',
  lastName => 'Doe'
}

resp = Net::HTTP.post_form(url, params)

resp_text = resp.body

The form encoding is application/x-www-form-urlencoded by default.

12.8. Using REST in Groovy

Groovy, a dynamic language for the JVM, has built-in support for REST. The RESTClient class is an extension of HTTPBuilder, designed specifically for making REST calls easier (for example, by having convenience methods for GET, POST, etc.).

Issuing GET Requests
Given RESTClient, it's pretty easy:

import groovyx.net.http.RESTClient
 
def client = new RESTClient( 'http://www.acme.com/' )
def resp = client.get( path : 'products/3322' ) // ACME boomerang

assert resp.status == 200  // HTTP response code; 404 means not found, etc.
println resp.getData()

The response field data is the parsed response content, always buffered in-memory.

Issuing POST Requests
Equally simple, using the same class:

import groovyx.net.http.RESTClient
 
def client = new RESTClient( 'http://www.acme.com/' )
def resp = client.post( path : '/user/details',
                        body : [ firstName:'John', lastName:'Doe' ] )

assert resp.status == 200

Here, too, the response is available in resp.getData().

13. For More About REST