The Representational State Transfer (REST) architectural style is not a technology you can purchase or a library you can add to your software development project. It is first and foremost a worldview that elevates information into a first class element of the architectures we build.
The ideas and terms we use to describe “RESTful” systems were introduced and collated in Dr. Roy Fielding’s thesis, “Architectural Styles and the Design of Network- based Software Architectures”. This document is academic and uses formal language, but remains accessible and provides the basis for the practice.
The summary of the approach is that by making specific architectural choices, we can elicit desirable properties from the systems we deploy. The constraints detailed in this architectural style are not intended to be used everywhere, but they are widely applicable.
Due to the Web’s prolific impact on consumer preferences, advocates of the REST style are encouraging organizations to apply the same principles within their boundaries as they do to external-facing customers with web pages. This Refcard will cover the basic constraints and properties found in modern REST web implementations.
What does Representational State Transfer mean? Transferring, accessing, and manipulating textual data representations in a stateless manner. When deployed correctly, it provides a uniform interoperability, between different applications on the internet. The term stateless is crucial piece to this as it allows applications to communicate agnostically. A RESTful API service is exposed through a Uniform Resource Locator (URL). This logical name separates the identity of the resource from what is accepted or returned. The URL scheme is defined in RFC 1738, which can be found here: ietf.org/rfc/rfc1738.txt
A sample RESTful URL might be something like the following fake API for a library:
What is actually exposed is not necessarily an arbitrary service, however, but an information resource representing something of value to a consumer. The URL functions as a handle for the resource, something that can be requested, updated, or deleted.
This starting point would be published somewhere as the way to begin interacting with the library’s REST services. What is returned could be XML, JSON or—more appropriately—a hypermedia format such as Atom or a custom MIME type. The general guidance is to reuse existing formats where possible, but there is a growing tolerance for properly designed media types.
To request the resource, a client would issue a Hypertext Transfer Protocol (HTTP) GET request to retrieve it. This is what happens when you type a URL into a browser and hit return, select a bookmark, or click through an anchor reference link.
For programmatic interaction with a RESTful API, any of a dozen or more client side APIs or tools could be used. To use the curl command line tool, you could type something like:
$ curl http://fakelibrary.org/library
This will return the default representation on the command line. You may not want the information in this form, however. Fortunately, HTTP has a mechanism by which you can ask for information in a different form. By specifying an “Accept” header in the request, if the server supports that representation, it will return it. This is known as content negotiation and is one of the more underused aspects of HTTP. This can be done using a curl command similar to the previous example:
$ curl –H “Accept:application/json”
This ability to ask for information in different forms is possible because of the separation of the name of the resource from its form. Although the "R" in REST is "representation," not "resource," this should be kept in mind when building systems that allow clients to ask for information in the forms they want. Possible URLs for our example library we might include are:
- http://fakelibrary.org/library - general information about the library and the basis for discovering links to search for specific books, DVDs, etc.
- http://fakelibrary.org/book - an “information space” for books. Conceptually, it is a placeholder for all possible books. Clearly, if it were resolved, we would not want to return all possible books, but it might perhaps return a way to discover books through categories, keyword search, etc.
- http://fakelibrary.org/book/category/1234 - within the information space for books, we might imagine browsing them based on particular categories (e.g. adult fiction, children’s books, gardening, etc.) It might make sense to use the Dewey Decimal system for this, but we can also imagine custom groupings as well. The point is that this “information space” is potentially infinite and driven by what kind of information people will actually care about.
- http://fakelibrary.org/book/isbn/978-0596801687 - a reference to a particular book. Resolving it should include information about the title, author, publisher, number of copies in the system, number of copies available, etc.
These URLs mentioned above will probably be read-only as far as the library patrons are concerned, but applications used by librarians might actually manipulate these resources.
For instance, to add a new book, we might imagine POSTing an XML representation to the main /book information space. In curl, this might look like:
$ curl –u username:password -d @book.xml -H “Content-type: text/xml” http://fakelibrary.org/book
At this point, the resource on the server might validate the results, create the data records associated with the book and return a 201 response code indicating that a new resource has been created. The URL for the new resource can be discovered in the Location header of the response.
An important aspect of a RESTful request is that each request contains enough state to answer the request. This allows for the conditions of visibility and statelessness on the server, desirable properties for scaling systems up and identifying what requests are being made. This helps to enable the caching of specific results. The combination of a server’s address and the state of the request combine to form a computational hash key into a result set:
http://fakelibrary.org + /book/isbn/978-0596801687
The GET request, which will be discussed later, allows a client to make very specific requests, but only when necessary. The client can cache a result locally, the server can cache a result remotely or some intermediate architectural element can cache a result in the middle. This is an application-independent property that can be designed into our systems.
Just because it is possible to manipulate a resource does not mean everyone will be able to do so. We can absolutely put a protection model in place that requires users to authenticate and prove that they are allowed to do something before we allow them to. We will have some pointers on ways of securing RESTful services at the end of this card.