Grokking the REST Architectural Style

This article was first published in the issue of php|architect magazine.

Representational State Transfer, or REST, has become the hip, new buzzword of Web 2.0. But what really makes an application RESTful? Is it pretty URLs? The use of XML over HTTP? Is it any web service that doesn’t use SOAP? In all of the hype, the definition of REST has become clouded and diluted.

Forget what you thought you knew about REST. Cast it aside. Leave it at the door. It’s time to take a fresh look at REST. This article re-examines REST, placing it under a microscope to uncover each of the constraints that form the crucial principles of the REST style.

Imagine a massive, dark cloud. It is so dark and vast that light cannot penetrate its interior, nor can one in the cloud ever conceive the concept of light at all. Light simply does not exist here. Chaos reigns in the darkness. There are voices and whispers in languages incomprehensible to human ears. It is deafening. Yet, despite the clear presence of a multitude of others moving every which way through the darkness, it is cold and lonely in this lawless land.

Sound like the early days of our universe? It’s not. This is the Web.

When Roy Fielding set out to define the principles of the Representational State Transfer (REST) style in his 2000 dissertation, he did not begin with a blank slate, deciding on components and fleshing out the details with the luxury afforded to an artist with a plain canvas. No, he began with a network already in existence: the Web. In an attempt to describe the way applications behave across that network, he conceived of a Web with no constraints-the dark, formless cloud-and began adding constraints to it, giving it shape. These constraints became the core principles of REST.

Forget what you thought you knew about REST. Cast it aside. Leave it at the door. Let’s take a journey through the Web, adding the constraints of the REST style one-by-one as we move forward to see how the Web-and REST-takes shape under these constraints.

The problem with many so-called RESTful services is that they aren’t RESTful at all. Perhaps they exhibit some of the traits of the REST style, but they miss the point of many of the constraints. For an application to take full advantage of the REST style, the entire network on which the application runs must be RESTful. This is because the REST style is intended for use in network-based software applications. Calling a single service “RESTful” is not enough because the service exists only on the server. There must be more, and this brings us to the first constraint of the REST style.

Of Clients and Servers

The constraints of the client-server architectural style are crucial to a RESTful application.

Let there be light. Now the cloud begins to take shape. It is no longer a dark, formless mass of meaningless messages traveling back and forth. There is a clear relationship between clients and servers, providing a separation of concerns.

In my talks, I have often stated that resources are the most important principle of the REST style, but this is not the full story. While resources are important, and I’ll discuss them later in this article, it is the client-server relationship that is the most important constraint of the REST style. It is this relationship that provides for a separation of concerns, simplifying the server component to improve scalability while the user interface component lives on the client side. As long as the interface between the client and server doesn’t change, the components may evolve independently.

In an application environment such as the Web, the client-server relationship is all-too-familiar. A web browser acts as a client. The web server is, well, the server. So, you may be scratching your head saying, “Well, duh, Ben!” Yet, I think we take this constraint for granted. The separation of concerns provided by this relationship enables many of the other constraints of the REST style, which is why I believe this to be the most important constraint. Without the client-server nature of the REST style, many of the other constraints would not apply.

No State Allowed

The next constraint is that of statelessness. Statelessness is an important part of the client-server relationship. Every request from the client to the server must contain all of the information needed for the server to sufficiently process the request. That is, all requests must be self-contained, or atomic. The client cannot send a request that relies upon previous requests. Every request must be interpreted in isolation.

Of course, since the early days of the Web, developers have been breaking its RESTful nature by implementing state in the form of cookies. In PHP and other web programming languages, even server-side sessions are not RESTful because a cookie must still be set in order for the client to tell the server which session to use. If the cookie goes away (either through expiration or some other means), then the server no longer knows which session to associate with the request. If cookies did not expire, were always guaranteed to be present in every request, and did not rely on a stored context on the server, then an argument could be made that the use of cookies can be RESTful. However, cookies are intended to expire, either at the end of the browser session or at some date set in the future. They cannot be relied upon, and thus, they cannot be thought of as part of an atomic request. Cookies are a way to maintain client-server state and, as a result, are not RESTful.

One may argue that client-server state provides valuable functionality, such as user login and functionality tailored to users’ preferences, but the REST style dictates that there should be no shared client-server state and, instead, the client should maintain all application state. This approach emphasizes scalability on the server and flexibility in the client implementation. Server scalability is an obvious benefit because there is no need to maintain a session store on disk, in a database, or in memory, so this is one less thing to consider and implement when scaling horizontally. Client flexibility may not be so obvious.

By allowing the client to control the state, the client can make data presentation decisions independent of the server. Take a simple RESTful shopping cart example. The client stores a user’s login information and sends it to the server through authentication headers only when a request requires authenticated access, such as finalizing a purchase. The client requests a catalog of items to purchase from the server, but when a user adds items to her cart, the actual cart information is stored locally in the client memory. The only time the cart data is sent to the server is at the point the user finalizes the purchase and checks out with her payment information. The server need never keep track from request to request of what items are in the cart. The request to purchase the items in the cart includes all the information necessary to complete the transaction.

Now, I understand that web browsers are not smart enough to provide this kind of rich client experience, but JavaScript and other client-side code are. This is another principle of the REST style called code-on-demand, which I will discuss later.

To Cache or Not To Cache

Next, we add the cache constraint. Again, this relies on the client-server relationship. The cache constraint specifies that data within a response be labeled as cacheable or non-cacheable. A cacheable response allows the client to store the response and use it again later when the same request is made, rather than send- ing the request all the way to the server. This improves scalability over the network by reducing the number of round-trip requests. The user sees a faster response time in the client, and the server never receives the request, so it doesn’t need to process any data.

As I mentioned earlier, the REST style is a style for network-based applications, so if a server returns metadata telling a client how to cache a response, then the client should respect the caching information and cache the response to reuse on subsequent requests. If it fails to do so, then the client breaks the RESTful nature of the application and also increases the load on the server by continuing to send requests for responses it might already have stored in its cache-or could have stored there.

In theory, all data in the application could be set as non-cacheable, but this decreases network efficiency and increases latency. The REST style seeks to improve performance over the network by allowing clients to cache responses, reducing the overall network traffic.

Speaking the Same Language

The next set of constraints defined by the REST style work together to form a uniform interface between the client and server. This is the constraint on which most tend to focus when discussing REST. I think this is because it is the most concrete concept, lending itself well to pseudo-code and real-world examples, particularly with Hypertext Transfer Protocol (HTTP).

The uniform interface is a distinguishing characteristic of the REST style. While other architectural styles- such as remote procedure call, or RPC-focus on the diversity of actions that the application can perform, giving rise to disparate systems across the network that all require different interfaces to communicate with each other, the REST style simplifies interactions by defining a uniform interface between components. This allows independent components, such as the client or server, to change while maintaining the same interface. Also, the same request may be made to other servers in the network, and each receiving server can understand the request. They may not be able to fulfill the request, but they all can understand it.

Fielding describes the uniform interface of REST as being composed of four constraints: “identification of resources; manipulation of resources through representations; self-descriptive messages; and, hypermedia as the engine of application state.”

Identity Matters

The first interface constraint, identification of resources, is often described as two separate topics when discussing REST: resources and addresses. Yet, these are one and the same in the context of the REST style, since a resource must have an address. Another word often used in the place of resource is noun.

Resources are all around. Take a look. I dare you.

Every object you see is bound to be a resource. The monitor in front you. The pen lying on top of the notepad that is sitting in your letter tray on your desk. These are all resources, and you’ll be hard-pressed to find something that isn’t a resource, but what makes a resource a resource?

Wiktionary defines a resource as “something that one uses to achieve an objective.” With this broad of a definition, practically everything can be considered a resource because everything can be used to achieve some objective or another. My monitor conveys information from the computer in a way that I can understand. I use the pen to write in the notepad, which I use to store my notes. The letter tray holds papers-and, in my case, mostly junk-and I use the desk as a workspace that supports my computer and all the resources I need to do my work.

In our case, though, we’re not talking about tangible resources, physical objects one can touch and interact with in the physical world. Rather, we’re interested in virtual resources on a network, like a document, image, or service. If you can request it over the network, it’s a resource, but a better way to define these types of resources is: if it has identity, it’s a resource.

Identity matters. When thinking about physical resources, a particular resource may or may not have an identity that specifies its location in space. Certainly, our brains give objects a kind of identity.

“Please pick up the pen that is on top of my desk.”

“Which pen?”

“The one lying next to the beer glass.”

“Oh. That pen.”

Objects in the real world have spatial identity. This is the same for resources in a network, but the space is virtual, and the address identifying a resource’s location is more exact. On the Web, we’re familiar with a Uniform Resource Locator (URL) as an address for a resource.

In the REST style, the focus is on resources and their identifiers, rather than on methods and actions. The diversity of resources is an important concept, since the network is capable of expanding to an infinite number of resources.

A RESTful system should expose these resources through hypermedia (which will be discussed later under “Resources Are Related”), and all resources should share the same interface for access and transfer of state. Clients may get resources, update them, and delete them. In addition, clients may create resources. These are analogous to the HTTP methods GET, PUT, DELETE, and POST. Without addressable resources with a uniform interface, there is no way for clients to make requests of servers, so the client-server relationship, again, is crucial to this constraint of the REST style.

One Identity, Many Representations

The second interface constraint is that of representations. Each resource has a representation such that the client never requests the resource itself but a representation, or a concept, of that resource. This allows the server to respond dynamically through content negotiation with a representation that satisfies the requesting client. There is never a need to change the links to the resource when the representation changes. The identity remains the same, though the representation changes.

In the REST style, whenever actions are performed on a resource, the client uses a representation of the current state of that resource and transfers that representation to the server to communicate a change in state. This is where the REST style gets its name. This is representational state transfer: the act of manipulating resources over a network by transferring representations between components to communicate changes in state.

Representations of resources are made up of media types, on the Web the most common of which is text/html, but others-specifically those common in web services-might include application/xml, application/xhtml+xml, application/atom+xml, application/soap+xml, application/json, and others, including binary media types, such as images. These media types all compose hypermedia elements of a greater hypertext system.

Hypermedia, the third interface constraint, is important in RESTful systems because the REST style places emphasis on the links between resources. In HTML, the most familiar links between hypermedia resources are found in the href attribute of the a element. These links allow users to move between resources as they wish.

In a RESTful service, resources should be linked together. Besides HTML, an excellent example of a format that makes use of links is the Atom Syndication Format (RFC 4287). Atom provides link elements that use rel attributes to specify relationships to the current resource. Listing 1 provides an example Atom Entry document with link elements for various types of related resources. An Atom client uses this information to expose these links to users.

Listing 1.
<?xml version="1.0" encoding="utf-8"?>
<entry xmlns="http://www.w3.org/2005/Atom">
<title>Grokking the REST Architectural Style</title>
<link rel="self" type="application/atom+xml;type=entry" href="http://example.org/articles/rest.atom"/>
<link rel="alternate" type="text/html" hreflang="en" href="http://example.org/articles/rest.en.html"/>
<link rel="alternate" type="text/html" hreflang="es" href="http://example.org/articles/rest.es.html"/>
<link rel="enclosure" type="audio/mpeg" length="1337" href="http://example.org/audio/rest.mp3"/>
<link rel="related" type="application/atom+xml;type=entry" href="http://example.org/articles/atompub.atom"/>
<id>tag:example.org,2009-02:articles/rest</id>
<updated>2009-02-01T12:29:29Z</updated>
<published>2009-02-01T08:29:29-05:00</published>
<author>
<name>Ben Ramsey</name>
<uri>http://benramsey.com/</uri>
</author>
<content type="xhtml" xml:lang="en">
<div xmlns="http://www.w3.org/1999/xhtml">
<p>Imagine a massive, dark cloud...</p>
</div>
</content>
</entry>

Resources Are Self-descriptive

The fourth and final interface constraint of the REST style is that of self-descriptive messages, or metadata. Metadata comes in the form of name-value pairs that can describe both the representation and the resource data returned in the response. Metadata provides extra information to the client about the representation, including the content type, the length of the data, the data encoding, etc. It may also contain control data, telling clients or other components how to cache the data or whether the resource has changed since the last request.

On the Web, metadata is contained in HTTP headers, such as in the Content-Type, Cache-Control, Content-Language, Content-Encoding, Content-Location, and Expires headers and more. The representation itself can also contain metadata. Again, Listing 1 shows an example of how a representation might contain metadata describing the resource it represents. The title, updated, published, and author elements all represent metadata describing the data contained in the content element. Even the content element has its own metadata in the type and xml:lang attributes.

Layers Bring It All Together

As the massive cloud that is the Web takes shape and gains structure imposed by these constraints, we come to the fifth constraint of the REST style, the layered system. This constraint builds upon each of the previous constraints to provide perhaps the most beneficial feature of the style. It is also the concept that many fail to grok when building RESTful applications.

In order to think about the constraint of the layered system, you must recall that REST is an architectural style to describe network-based software applications. The key word here is network. The REST style depends on the presence of a network. All of these constraints work together over the network to reduce load on the server while improving application response in the client (reduced latency, etc.). This creates a highly efficient network application that scales horizontally with the network.

The layering effect of the network restricts each component from being able to see beyond the current layer. This makes each layer independent of the others. Each layer only needs to know about the request or response and the destination of the message.

This is where statelessness, caching, and a uniform interface play major roles. It is these constraints that allow the layering to take place at all because all components along the path of the request can understand the request (a benefit of the uniform interface) and store and replay that request (due to the statelessness of the self-contained messages) and even serve the responses (stored in the local cache) rather than sending the request along to the server.

This type of system makes it very easy to drop in intermediaries in the form of load balancers, proxies, gateways, firewalls, etc., each of which can respect the cache metadata to store the response of the request in cache. This means that the layers work within the network to improve the performance of the overall application-remember, the network is part of the application-by reducing the number of round-trip requests to the server and returning a response to the client in a shorter amount of time than it would take the server to process the request.

I believe that many so-called RESTful applications forget that the network and its layers are part of the complete application. This short-sightedness means that these applications fail to take advantage of caching and statelessness, requiring that every request go from the client all the way to the server and back. These applications miss the point of the REST style, dumbing it down to POX (Plain Old XML) over HTTP transactions, usually focusing on “pretty” URLs.

Extending the Client

Finally, there is one last constraint of the REST style, though it is considered optional. It is the code-on-demand style, which I mentioned earlier when discussing statelessness. This style of application architecture should be all-too-familiar to modern web developers since it is a way to allow the server to extend client functionality by telling the client to download and execute extra code to improve and enhance the client experience independent of server interaction.

These days, we do this in the form of JavaScript, Cascading Style Sheets (CSS), Flash, and more. A RESTful application should take advantage of code-on-demand to move all state functionality to the client, as well as providing other functionality that is more appropriate and efficient to handle in the client rather than on the server.

Getting Some REST

We’ve taken a journey through the Web, one-by-one adding the constraints of the REST style to see how the massive, formless beast of the Web has a shape and a form and that, beyond the seeming chaos, there is order and structure. Yet, the structure is very light-weight, and all of the components are contained in distinct and separate layers that know nothing of each other. Still, the uniform interface they share makes it simple enough for each layer to understand the messages sent back and forth and to relay those messages, caching data, as needed, to provide a more efficient and scalable network.

This is the REST style in a nutshell. Client-server, stateless, cacheable, uniform, layered. It is not a web service. It is not a protocol. It does not dictate a particular data format. REST is the manipulation of resources by transferring representations between network components that share a uniform interface.

While this has not provided a practical discussion of how to design and implement RESTful applications, it is my hope that you now have a greater understanding of the principles of the REST style and will be able to take these principles and apply to them to your own network-based (web) applications, taking full advantage of the network and its components to build highly scalable applications with rich clients.

Now, go get some REST!


Principles of REST

A network-based application is considered RESTful when the following constraints are applied and none are broken.

  • Client-server: Provides full separation of concerns
  • Stateless: Each request contains all of the information necessary to be understood and processed; no shared context exists between the client and server (i.e. cookies, sessions)
  • Cache: Clients may reuse data that is labeled as cacheable, improving network efficiency
  • Uniform interface: Components throughout the network share a uniform interface
    • Resources: There are an infinite number of resources, all of which have unique addresses and share a common interface for manipulation
    • Representations: A resource may be represented by multiple media types, and the representation is the primary vehicle for a resource’s transfer of state
    • Hypermedia (Links): Resources should be linked to other resources
    • Metadata: Describes the data contained in the representation or other metadata
  • Layered: All components in the network can understand all requests as they travel from client to server but they cannot see beyond the current layer; provides scalability and efficiency of requests
  • Code-on-demand: Extends the functionality of the client with client-side scripts, etc.

REST Vocabulary

Hypermedia
The use of media as elements of a hypertext system in which elements are connected by links
Layer
An individual component within the network; may be a client, server, gateway, proxy, etc.
Representation
A media type (e.g. text/ html) used to communicate a change in the state of the resource
Resource
Anything that has identity
RESTful
An application is said to be RESTful when it adheres to the principles of the REST style
RESTafarian
An advocate or extreme zealot of the REST style

For More Information