My Understanding of REST Architecture

REST is such a misunderstood and yet overused term that I thought I’d share my understanding of the term and usage patterns.

REpresentational State Transfer (abbreviated as REST) is a simple way to organize interactions between independent systems.   This means that:

  • Everything is Represented as a Resource
  • Resources have State
  • Resource State is Transferred over the wire (HTTP)

The design rationale for REST is based on the fact that the web is a massively scalable distributed software system that works really well.  We should therefore be able to use the success of its underlying architecture to build integrated systems more easily.  Due to their relative simplicity clients usually find it really easy to interact with REST APIs.

Why is REST usually referred to as an “Architectural Style” it’s useful to first establish what it is not:

  • REST is not a Standard such as HTML, CSS, XML or WSDL. The W3C will not ratify REST
  • REST is not a Protocol such as HTTP or SOAP

REST Constraints

REST was inspired by the simplicity and robustness of the Web itself and was first described in his PhD dissertation by Roy Fielding.   It was designed as a set of Constraints on top of HTTP which are detailed below.

1. Client-Server

The principle of Separation of Concerns encourages us to isolate the user interface from data storage and business processing concerns.

The result is:

  • Improved portability of UIs across OS and device platforms
  • Improved scalability by simplifying server components
  • Client and Server components are allowed to evolve independently

2. Statelessness
The next constraint to the client-server interaction is that communication must be stateless.  The server should not be relied upon to maintain application state by storing session objects.  Each request from client to server must contain all of the information necessary to understand the request, and cannot take advantage of any stored context on the server. Session state is therefore kept entirely on the client.

Note that imposing statelessness is a tradeoff in which simplicity and scalability may come at the expense of increase in network traffic since the server “forgets” application state between requests.  This tradeoff is normally addressed by adjusting the grain of the exchanges between client and server to reduce chattiness. In general REST is most efficient for large-grain resources.

3. Cache
As with the web, the state of HTTP accessible REST resources can be persisted in a client-side cache so we don’t have to hit the server each time.  The Cache constraint requires that resource be identified as cacheable if appropriate. If a response is cacheable, then a client can choose to cache and reuse that response for subsequent requests for a configurable period of time.

4. Uniform Interface
The uniform interface constraint ensures that our API looks and behaves consistently across requests and time, thus allowing each part of the API to evolve independently.

The four parts of this interface that must remain uniform are:

  1. Resource Identification

Resources are uniquely identifiable using URIs such as:

http://api.csc.com/employee/ecartman

 

  1. Resource Representation

Each resource must have a representation which is produced as a response when it is requested using its resource identifier.  For example, a URI GET request for the resource

GET http://api.example.com/founder/ecartman

may return the following state representation:

{
  “id”: “123456”
  “name”: “Eric Cartman”,
  “role”: “Founder”
}

Furthermore, this representation must contain enough information to subsequently modify or delete the resource on the server should it have permission to do so.

  1. Self-Descriptive Messages

Each client request and server response is a standard http message consisting of a body and headers.  The body+headers should contain all the information necessary to complete the requested task on both ends of the exchange.  For example, response messages should explicitly indicate their cacheability.

This type of message exchange is also referred to as stateless and context-free.

  1. Hypermedia as the engine of application state (A.K.A. HATEOAS)

Clients make state transitions only through actions that are dynamically identified within hypermedia by the server (e.g., by hyperlinks within hypertext). Except for simple fixed entry points to the application, a client does not assume that any particular action is available for any particular resources beyond those described in representations previously received from the server.

5. Layered System
The Layered System constraint dictates that a client need have no knowledge of whether it is connected directly to the end server, or to an intermediary or proxy on the way to the server. Use of intermediary servers may improve system scalability by enabling load-balancing and by providing shared caches. They may also enforce security policies.

6. Code on Demand (Optional)

The Code on demand constraint allows servers to extend the behavior of a client by sending code to be executed on the client.  This code usually takes the form of javascript.  We’re used to seeing this on web pages, but the very same capability can optionally be used in a REST API.

References

My Understanding of REST Architecture

Leave a Reply

Your email address will not be published. Required fields are marked *