REST stands for REpresentational State Transfer. A REST-ful web service is one that emphasizes the ideals of the REST architecture – flexibility (scalability & generality), low coupling (client and server can manage their resources however they want as long as they agree on the API), and lack of constraints with message formats (when compared to equivalent architectures like CORBA). For a more complete discussion of REST straight from the horse’s mouth see Roy Fielding’s PhD dissertation.
The idea of REpresentational State Transfer can be derived from thinking of computers on a network as having resources (data such as files, database records, etc,..) that they exchange in order to implement distributed applications. The components of a distributed application do not reside in one place (as is the case with a stand-alone program on a single computer such as a text editor), but across multiple machines (or hosts). The concept of “state transfer” refers to the ability of a client (the machine that initiates the transfer) to request CRUD (Create,Read,Update,Delete) transactions from a server. Each transaction will cause a change in state either on the client (requester) or the server (responder). “Read” transactions change the state of the client, while “Create”,”Update”, and “Delete” transactions are meant to change the state of resources on the server.
A Web Browser talking with a Web Server in order to implement the distributed application we know of as the browsable internet is a basic example of RESTful Web Services at work. Of course there are many other software & hardware layers involved in supporting the internet (per the OSI model), but let’s ignore those for now. We all know that your basic webpage address (also called a URL, or Uniform Resource Locator), starts with “http://” or “https://”. This is because the browser and web server are using HTTP (HyperText Transfer Protocol) or HTTPS (HTTP-Secure) to negotiate transactions such as loading a certain webpage or receiving file uploads. HTTP is a request/response protocol in that a client (such as the browser) requests a resource (such as a webpage “/exclusives/superpark-16-day-4-photos-recap/index.html” from host “www.snowboardermag.com”), and the server responds with an HTTP code and response body (the webpage if the request was successful).
Here is a sample request/response for the aforementioned webpage (slightly simplified)..
GET http://www.snowboardermag.com/exclusives/superpark-16-day-4-photos-recap/ HTTP/1.1 Host: www.snowboardermag.com User-Agent: Mozilla/5.0 (X11; Linux i686; rv:12.0) Gecko/20100101 Firefox/12.0
HTTP/1.1 200 OK Content-Type: text/html; charset=UTF-8 Date: Tue, 29 May 2012 07:31:44 GMT Server: Apache/2.2.3 (CentOS) <!DOCTYPE html> <!--[if IE 6]><html id="IE6" lang="en-US"><![endif]--> <!--[if IE 7]><html id="IE7" lang="en-US"><![endif]--> <!--[if IE 8]><html id="IE8" lang="en-US"><![endif]--> <!--[if (gt IE 8)|!(IE)]><!--> <html lang="en-US"> <!--<![endif]--> <head prefix="og: http://ogp.me/ns# fb: http://ogp.me/ns/fb#"> <meta charset="UTF-8" /> <title>Superpark 16: Day 4 Photos & Recap | Snowboarder Magazine</title> <meta name="description" content="<strong>Recap: T. Bird</strong><br clear=left> ...
Let’s look at some key components of the request and response. The browser issues a “GET” method request for a resource named “http://www.snowboardermag.com/exclusives/superpark-16-day-4-photos-recap/” from a host (server) named “www.snowboardermag.com”. It also sends a few other bits of potentially useful information. The response from the server contains an HTTP code, 200 (which means “OK”), and the requested resource (the webpage). There are other HTTP request methods, but browsers mostly use only GET or POST. There are also many other HTTP response codes web servers will typically use:
- 301 “Moved Permanently”
- 302 “Found”
- 400 “Bad Request”
- 403 “Forbidden”
- 404 “Not Found”
- 500 “Internal Server Error”
To see another of these return codes in action, let’s check out a goofy request for a non-existent resource:
GET http://www.google.com/easter-bunny-and-his-furry-friends-on-mars/ HTTP/1.1 Host: www.google.com User-Agent: Mozilla/5.0 (X11; Linux i686; rv:12.0) Gecko/20100101 Firefox/12.0
HTTP/1.1 404 Not Found Content-Type: text/html; charset=UTF-8 Date: Tue, 29 May 2012 07:40:34 GMT <title>Error 404 (Not Found)!!1</title> ... <p>The requested URL <pre>/easter-bunny-and-his-furry-friends-on-mars/</pre> was not found on this server. <ins>That's all we know.</ins> </p>
A wise browser will realize the folly of the request and let the user know to go fish. The server has also provided webpage content to alert the user in a more human-readable way that a request has been made for a resource that does not exist. The browser will display that content.
So there it is, a simple trimmed-down example of a REST Web Service. If we desire more functionality than just uploading/downloading content between a browser and web server, we will need to use other HTTP request methods besides GET and POST. Here is a more complete list of the methods we could use:
HTTP request methods function like verbs. With the browser example a request can “GET” a resource (such as a webpage or image file), or “POST” data to the server for it to save as a file or in a database (this is the case when submitting an online form or uploading a document). The other methods are similar but rarely used with browsers. They are however available for other applications that use a REST API (Application Programming Interface). Each request will still contain 1) a method, 2) a resource identifier, and 3) optionally a request body (such as content to upload). Each response will contain 1) a response code, 2) optionally a response body (such as a webpage).
Request/Response Body Content is classified by what format is used to transmit information. As can be seen in the example responses above, “text/html” is a common response body “Content-Type” (also called a MIME type). There are a myriad of other content types available for request/response bodies. Here are some commonly used types:
MIME, or content-types are very similar to file extensions in that they identify what format the file (or content) is in and consequently, how best to interpret it. In fact, each of the above content-types could be given an extension if it were a file:
This quick introduction will come to a REST with an example REST request that an application could use to GET a list of buckets (data storage containers) held by a certain user’s account, and the server’s XML response. The specific example is not so important, I’m just trying to illustrate how a REST API can be used outside of the browser/web-server examples given above to complete a client/server transaction. Note that the requested resource “/” refers to the “root” or top-level index of resources the server provides. The “Authorization” field in the request identifies to the server which account the application wants to query and provides authentication credentials to prove it is authorized to make the request. So the resulting request is asking the server for a top-level index of “S3 bucket” resources that are held by the account identified and authenticated in the “Authorization” field. In this particular example, the API specifies that the response body content-type will be XML. It could’ve also been in another format such as plain text or JSON.
(adapted from GET Service – Amazon Simple Storage Service 5/28/2012)
GET / HTTP/1.1 Host: s3.amazonaws.com Date: Wed, 01 Mar 2009 12:00:00 GMT Authorization: AWS AKIAIOSFODNN7EXAMPLE:xQE0diMbLRepdf3YB+FIEXAMPLE=
HTTP/1.1 200 OK Transfer-Encoding: chunked Date: Tue, 29 May 2012 08:36:39 GMT Server: AmazonS3 <?xml version="1.0" encoding="UTF-8"?> <ListAllMyBucketsResult xmlns="http://doc.s3.amazonaws.com/2006-03-01"> <Owner> <ID>bcaf1ffd86f461ca5fb16fd081034f</ID> <DisplayName>webfile</DisplayName> </Owner> <Buckets> <Bucket> <Name>quotes</Name> <CreationDate>2006-02-03T16:45:09.000Z</CreationDate> </Bucket> <Bucket> <Name>samples</Name> <CreationDate>2006-02-03T16:41:58.000Z</CreationDate> </Bucket> </Buckets> </ListAllMyBucketsResult>