REST - The short version

Date: 2008-05-28
Author: Mike Amundsen

Abstract

This document presents a short definition of the Representational State Transfer (REST) architectural style. It outlines the four REST constraints and offers two additional aspects of the REST style important for building Internet-scale applications for the Web.

Getting a clear handle on the definition of the REST architectural style can be daunting. While there is no shortage of descriptions available, I did not find many of them helpful at first. Also, as I began talking about REST to colleagues, I often had a difficult time producing clear descriptions for the key points. Over time, however, I sharpened my summary into a version that seemed to make sense to most of my listeners. I offer here my rendition of the REST model.

A definition

First, here is a succinct definition of REST from the Conclusions section of Fielding's 2000 dissertation:

REST is a coordinated set of architectural constraints that attempts to minimize latency and network communication while at the same time maximizing the independence and scalability of component implementations. This is achieved by placing constraints on connector semantics where other styles have focused on component semantics. REST enables the caching and reuse of interactions, dynamic substitutability of components, and processing of actions by intermediaries, thereby meeting the needs of an Internet-scale distributed hypermedia system.

As mentioned in the above quote, REST is often described as a set of constraints. Here, again using a quote from Fielding's work, is the set of constraints that defines the REST pattern:

REST is defined by four interface constraints: identification of resources; manipulation of resources through representations; self-descriptive messages; and, hypermedia as the engine of application state.

And here is each one, in turn:

Identification of resources

Every interesting resource has its own unique URI. This URI can be used to request an instance of the resource. For example: http://example.org/users/ is a URI that might return a list of users. The URI is the identifier. The resulting list of users is the resource.

It is important to note that a resource is not a 'storage object' but is, instead, conceptual entity. Resources represent some identified item that can be accessed - nothing more. The identifier (URI) is passed from the client to the server where it is resolved into a resource that is returned from the server to the client. Just how the server uses the identifier to 'construct' the resource is of no real importance to the client.

Manipulation of resources through representations

An identified resource can be returned in various formats such as HTML, XML, SVG, JSON, PNG, etc. These formats are representations of the identified resource. The list of possible formats (Media Types) understood by clients and servers is constrained and each format is well-defined.

REST-ful applications may support more than one representation of the same resource at the same URI. And REST-ful applications allow clients to indicate which representation of a resource they wish to receive. This is accomplished via the Accept HTTP header that is passed by the client to the server with each request for a resource.

Resources can be updated (or added) by sending representations from the client to the server. REST-ful applications may support more than one representation for updates to the same resource. And REST-ful applications allow clients to indicate their preferred representation when sending data to the server. This is accomplished via the Content-Type HTTP header that is passed by the client to the server with each resource sent to the server.

The de-coupling of the representation of the resource from the URI that identifies that resource is a key aspect of REST.

Self-descriptive messages

Each client request and server response is a message and REST-ful applications expect each message to the self-descriptive. That means each message contains all the information necessary to complete the task. Other ways to describe this type of message is "state-less" or "context-free." Each message passed between client and server can have a body (or 'entity body') and metadata.

REST-ful applications also operate on the notion of a constrained set of message types that are fully understood by both client and server. The document that defines HTTP 1.1 outlines eight message types (HTTP Methods) that can be sent to HTTP servers. Six of them are widely used today. They are: GET, HEAD, OPTIONS, PUT, POST, and DELETE. The first three are read-only messages. The last three are update messages. There are well-defined rules for how clients and servers are expected to behave when using these messages. The names and meanings of the messages metadata elements (HTTP Headers) are also well-defined. REST-ful applications understand and follow these rules very carefully.

Hypermedia as the engine of application state

Sharing representations by sending self-descriptive messages to identified resources changes the state of the application. For example, successfully POSTing a representation of a new "user record" to the server will change the state of the application by growing the list of users by one. Requesting a list of users (via GET) can return the new state of the application. Both POSTs and GETs are accomplished via hypermedia links.

In an HTML browser, GETs are accomplished by clicking on anchor tags that have an attribute ("href") which contains a resource URI. POSTs are handled by pressing the "Submit" button within a form tag that has a URI attribute ("action"). Note that the anchor and form elements were sent by the server to the client as part of the representation of the requested resource. In this way, a REST-ful application enables the server to inform the client of the possible ways to change the state of the application via hypermedia.

Additional considerations

In addition to the four primary interface constraints outlined above there are two other optional constraints important to REST-ful applications. These are 1) support for intermediaries; and 2) code-on-demand.

Support for intermediaries

Sharing resources using self-descriptive messages makes it possible for both client and server can take advantage of intermediaries (proxies). Intermediaries can be used to cache the results of requests, act as firewalls between clients and servers, and other tasks. Since REST messages are self-descriptive and their semantics are well-defined, REST-ful intermediaries can be safely added and removed at any point along the stream between client and server without breaking the communication line or requiring servers or clients to 'upgrade'.

Code-on-demand

REST-ful applications may also be able to take advantage of clients that support "code-on-demand." For example, Web browsers may allow servers to return scripts or links to applets that can be executed at the client. This additional code execution can extend the capabilities of the client without requiring the user to install new client software.

About the Author

Mike Amundsen Mike Amundsen lives and works as a contract programmer in Kentucky, USA. He currently spends most of his time creating and supporting large-scale web sites running under Windows and ASP.NET. In the past, he spent quite a bit of time as a trainer/speaker and was involved in the writing of several books on programming with Microsoft technologies.

Comments