REST is a buzzword that confuses many people. Even after my initial experiences using RESTful APIs, I still couldn’t adequately define or explain exactly what REST is. Unfortunately, the majority of educational materials on REST tend to be too conceptual, lacking enough examples to help you get a tangible understanding of the subject. Even worse, there’s a lot of misinformation about REST, and the terminology used to explain REST is often misleading.
REST stands for Representational State Transfer, and it’s actually an architectural style rather than a framework or programming language. In a nutshell, “State Transfer” refers to transferring the state of an application or resource. The word “Representational” refers to how representations of a resource are used to communicate the current state of that resource, the intended state of the intended resource, or the state of a different resource altogether. XML or JSON data is often used to represent the state, although REST is not limited to XML and JSON. Any document, file, image, or hypertext could be a representation of a resource. The HTTP protocol is generally used for communication between the client and the server. However, the HTTP protocol is not a requirement, any protocol that provides the necessary communication between the client and server is fine. Keep in mind that just because an HTTP service returns XML or JSON doesn’t necessarily mean that it’s RESTful. There are several constraints for a service to be truly RESTful, and if any of the constraints are violated then the service is not truly RESTful. I place emphasis upon this concept because REST is a buzzword thrown around liberally, even where it doesn’t belong. Just because a service is REST-like doesn’t necessarily mean that it’s truly RESTful.
So what’s the difference between a REST architecture and a REST-like (or unlike) architecture? There are several REST constraints, all of which (except Code-On-Demand) must be satisfied in order for a service to be considered truly RESTful. If you have worked with a so-called RESTful service in the past, you might notice that it actually violates one or more of the required constraints (which isn’t necessarily good/bad in itself; it simply means that the REST label doesn’t accurately reflect the nature of that service). Outside of these constraints, there’s quite a bit of space for creativity and thinking outside of the box.
- Client-Server Constraint
This constraint is quite simple, and it means that there’s a client component and a server component. The client-server constraint is based upon the separation of concerns principle (separation of concerns is involved with other constraints as well). Separation of concerns improves both portability and scalability, while also making it easier to modify the various components. The server could be running Apache, IIS, or some other web server software, and could still process requests from any client. Likewise, the client could be running Windows, Linux, or OSX; virtually any client should be able to communicate with virtually any server. Also, the underlying logic of the service should be irrelevant to the user. Changing the way the service works behind the scenes shouldn’t really impact the user interface, and vice versa.
- Stateless Interaction Constraint
This constraint may seem confusing to you. After all, isn’t “State Transfer” part of the definition of REST? However, the statelessness constraint doesn’t mean that state never exists in any way with machines that use a RESTful service, nor does it mean that application or resource state doesn’t exist. The true meaning of the stateless constraint is that the actual interaction between the client and the server is stateless between requests; each interaction is independent. The application state is controlled and stored on the client side. Requests from the client to the server must contain all the information needed for the server to process the request. On one hand, since all of our requests must contain all of the relevant information, there may be repetitive data between requests, which decreases efficiency and increases the size of each request. On the other hand, the server doesn’t need to maintain data from past requests, nor does it need to process that past data to complete an active request. In many cases, the advantages outweigh the disadvantages.
- Cache Constraint
All data must be labeled as either cacheable or non-cacheable. Cacheable data may be reused by the client in future requests to increase efficiency and performance. On the other hand, reliability may also be decreased, as the data in the cache may be reasonably different from the data that would be returned by a request. The cache constraint makes up for some of the decreased efficiency from the stateless interactions constraint. Cacheable resources should additionally specify an expiration date/time for the cached data.
- Layered System Constraint
A REST service may consist of multiple layers, and each layer may not see past the layer that it interacts with.
- Code-On-Demand Constraint (optional)
Servers can transfer executable code to a client as applets or scripts. This is the only optional constraint.
- Uniform Interface Constraint
This specifies that information is transferred in a standardized way. It consists of four sub-constraints:
- Identification of resources – Each resource has a unique identifier (the identifier is generally, but not always, a URI accessed via HTTP).
- Manipulation of resources through representations – Each resource may have one or more possible representations. For example – JSON, XML, or raw text. The client may access and/or manipulate a resource by using one of these representations.
- Self-descriptive messages – Both requests and responses contain information (whether it be in the body, the header, or both) that adequately describes how to handle the request/response.
- Hypermedia as the engine of application state (HATEOAS) – This constraint is important, and to understand it we should first understand the idea of hypermedia. Hypermedia is based upon the idea of hypertext, which is any text that contains links to other texts. Hypermedia expands upon this principle to include any kind of media, such as sounds or images. Therefore, linking is used to drive the state of the application.
For more information on the constraints and general theory/concepts of REST, you should read Roy Fielding’s doctoral dissertation at: http://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm
The ideas of REST were developed by Roy Fielding, and therefore his documentation of REST should be considered the most trustworthy resource on the subject.
Examples and Practical Applications
The underlying architecture of the World Wide Web is actually based upon REST. GET requests with REST, which are quite common, are essentially just a URL. Parameters may be passed to the URL in the following fashion:
In this case, the two parameters are tracking (which could represent a tracking number for a package) and carrier (which could represent a particular shipping carrier). The index parameter could specify the most current tracking data available for that shipment. The ampersand symbol (&) is used much like a comma is used in English, so that we may add multiple parameters to a single URL. The equals symbol (=) is used to assign an actual value to each parameter. We could use other symbols besides the ampersand or equals symbol for these purposes, but those symbols are frequently used for assigning and separating values. In the above example, 635776951234 is assigned to the tracking parameter, and fedex is assigned to the carrier parameter. This particular example is something that I simply made up off of the top of my head (the URL in Figure 3-1 doesn’t actually exist as far as I know). I have worked with similar REST APIs designed for shipping purposes in the past (mostly for generating reports that highlight the quality of service provided by different shipping carriers), although this article isn’t about any particular API. An example of a response from the request in Figure 3-1 could be in XML format, like so:
<address>123 Rabbit Hole Lane</address>
<summary>Delivered, front door</summary>
<link href="/shipment/info?tracking=635776951234&carrier=fedex&index=last" rel="this" />
<link href="/shipment/info?tracking=635776951234&carrier=fedex&index=3" rel="prev" />
The XML in Figure 3-2 could represent a response from the server about the details of a package. It includes information about the destination address, the date the package was shipped, the specific shipping service used, and the status of the package (including both a summary of the last tracking update, and the date/time of the update). It also contains hypermedia links to both the URL of the tracking data in the response and the URL of the previous tracking record. This data could just as easily be in JSON format. CSV (comma separated values) is also a common format, although CSV is usually very limiting unless only a simple data structure is needed. The response data could even be an image file.
Requests that are more intricate may be more troublesome to use with a GET request. Since REST requires that the entire state is transferred in each request, this can lead to very long URLs in some cases. Moreover, GET requests are less secure than POST requests, and REST doesn’t really offer any built-in security (security is something the developers of the service must implement themselves). Therefore, POST requests are often used with RESTful services too. In addition to being used for requests containing large amounts of data, POST requests are generally used for performing insert/update/delete operations. Although a GET request could technically be used for performing insert/update/delete operations, that’s considered bad practice and an improper use of GET (as a GET request is literally meant to GET or retrieve data).
There are all sorts of different RESTful services, the above example relating to shipping is only one possible example. There are RESTful services for everything ranging from public transportation to social media. The possibilities are virtually endless with REST based APIs. We’ve gained a basic understanding of REST that should allow you to comfortably use REST services. If you continue to build upon this foundation, you may even go on to create REST services of your own.