MindTouch Developer Center > REST > REST for the Rest of Us

REST for the Rest of Us

    

Overview: This article is an introduction to REST web-services.  It covers the basic web interactions of REST and showcases common REST design patterns that can be put to immediate use.

    

REST is a quickly emerging style for interacting with web-services.  The term "REST" was coined by Roy T. Fieldingin his PhD dissertation and describes a new architectural style for hypermedia distributed systems.  The beauty of this style is that it builds on what makes the world wide web so scalable.  This shouldn't be a surprise given Dr. Fielding's involvement in defining the web's building blocks in the early 90s.

    

So, what makes REST so appealing?  The answer is simplicity.  Instead of requiring a whole new set of technologies, it builds directly on what we have today and what we are familiar with.  Except, it applies it in a novel and practical way.  So, let's explore what REST means to you.  This introduction will cover some HTTP basics and then dive into guidelines showing how to apply REST to your web-services.

Resources and URIs

Resources are referred to by a uniform resource identifier (URI).  Because URIs are managed in a decentralized fashion, they are well suited to naming resources.  Two resources with the same URI are usually the same.  Determining if two distinct URIs refer to the same resource is generally not possible without some insider knowledge or additional information.  We'll delve into this problem further once we have laid down the ground rules for interacting with resources.

    

Concept: One of the wonderful properties of URIs is that they can be transmitted to another party and still make sense.  Compare this to when you map a network drive under Windows to the letter "S:".  When you send the location of the quarterly sales forecast to your co-workers (e.g S:\sales\2007\q1\forecast.xls), they might not be able to access it, because their "S:" drive doesn't exist or maps to another network drive.  This isn't the case with URIs.  Regardless of where you are in the world, if there is a way to reach the resource, you'll be able to get to it.

    

A URI has a structure as well.  It's composed of five parts called scheme, host, path, query, and fragment.  Consider the following URI:

http://www.domain.com/name/of/resource?limit=10&offset=0#bookmark

    

We can decompose this URI as follows:

Part
Sample
Meaning
scheme http
The scheme represents the protocol used to communicate with the resource.  It is usually http or https for web resources, although, there are no limitations to what schemes can be used.  There are many standard schemes defined and an unknown number of proprietary ones exist as well.
host www.domain.com
The host determines the server on which the resource is located on.  The host part is optional in URI.  When omitted, the URI contains only relative information, which can only be interpreted in the context of a non-relative URI.
path /name/of/resource
The path determines the precise resource on the server.
query limit=10&offset=0
The query instructs the server to apply additional operations to identify the part of the resource that is desired or how its representation should be returned.
fragment bookmark
The fragment is not transmitted to the server and is only applied client-side.  Thus, it has no effect on server-side processing.

    

Since a URI is made of multiple parts, it's important to define what it means for a URI to identify a resource.  In Dream, a resource is identified by a URI up to the query part.  Thus, http://www.mindtouch.com/deki and http://www.mindtouch.com/deki?query-argument represent the same resource.  Other systems may use the entire URI to identify resources.

    

Resources, Verbs and Content-Types

Once the resource has been reached, it needs to be acted upon to accomplish work.  In REST, all operations are described by four simples verbs: GET, PUT, POST, and DELETE.  These verbs are a subset of the verbs defined in the HTTP protocol, but are all that is needed.

    

We will use the following notation to show the verb and the resource name:

GET http://myserver/abc/xyz

    

Finally, when transferring data, either from or to a resource, it may be important to know what type the data has.  This is captured by the content-type header in the HTTP request or response.  There are many standard content-types such as "text/plain" for plain text files, "image/png" for PNG images, and so on, which can be used to define smart behaviors, but these are beyond the scope of this introduction.

Resources and Representations

The last important bit is the distinction between a resource and its representations.  A resource is the real thing that is being acted upon with a request.  For example, deleting a file from a folder, adding an entry to a blog, or reading the heart rate of a patient.  The data transmitted to and from the resource is a representation of it.  Sometimes the representation can be faithful, such as in a file copy, and sometimes it's just a description, such as the sound of someone's voice.  The end effect is that we never send or receive resources, only their representation.  The format of the representation is determined by the content-type.  And the interaction of the representation on the resource is determined by the verb.

REST Verbs

Now, let's see how we can explore these four basic verbs to define application behavior.

GET

The GET verb is used to read a resource.  An important rule of thumb is that a GET operation is safe.  That is, it can be done repeatedly without changing visibly the state of the resource.  This property is very important for various reasons.  First, indexing engines use GET to index the contents of a resource.  So it would be bad if indexing a resource also changed it.  Second, intermediaries, such as proxies, may cache results of a GET operation to accelerate subsequent accesses to the same resource.

    

Let's assume we have an image as a resource at "http://myserver/myphotos/mywedding.img".  We can retrieve this image by doing a GET operation on it:

GET http://myserver/myphotos/mywedding.img

    

Similarly, we can also query a complex resource, such as a blog, to get parts of the data:

GET http://myserver/myblog/2006-12-25T11:12:05.001Z/comments?query=author:anonymous

    

The GET verb is the fundamental read operation for resources.  All data resources support GET, but not all behavioral resources do.  While a GET request cannot have side-effects, it can return only parts of the resource.  This means that GET can act as both a read operation and a query operation.

PUT and DELETE

The PUT and DELETE verbs allow a request to alter the state of a resource atomically.  For example, if we wanted to change the image of our earlier example, we could upload a new one using the same URI and the PUT verb:

PUT http://myserver/myphotos/mywedding.img

    

This operation would indicate to the server that we want to replace the target resource with the contents of our request.

    

Similarly, if we wanted to delete the image, we could use the DELETE verb:

DELETE http://myserver/myphotos/mywedding.img

    

This operation states we want the server to delete or reset the target resource.

    

The PUT and DELETE verbs give us a simple mechanism to replace or destroy a resource.  Note that PUT and DELETE apply to the entire resource and not just parts of it.  So, when doing a PUT operation, the entire resource is replaced.  This detail is very important.  Important enough to be repeated: PUT acts on the entire resource!  The same is true for DELETE: DELETE acts on the entire resource!

    

The PUT and DELETE operations are atomic.  If two PUT operations occur simultaneously, one of them will win and determine the final state of the resource.  The same is true when a PUT and DELETE operation occur simultaneously.  Either the resource's final state is updated or it is deleted, but nothing in between.  In the case of two simultaneous DELETE operations, the order does not matter, because deleting a resource again has no effect.

POST

The POST verb can carry a variety of meanings.  It's the Swiss Army Knife of HTTP verbs.  For some resources, it may be used to alter the internal state.  For others, its behavior may be that of a remote procedure call.

    

In the example of our blog, we could add a new blog by using the POST verb:

POST http://myserver/myblog

    

The POST operation is very generic and no specific meaning can be attached to it.  In general, use POST when only a subset of a resource needs to be modified and it cannot be accessed as its own resource; or when the equivalent of a method call must be exposed.

REST Patterns

The previous section introduced the basic HTTP verbs and their associated semantics.  This section explores basic patterns of how these verbs can be combined to provide a rich REST application interface.

Entity Pattern

The entity pattern applies to resources that can be read with a GET operation, but can only be changed by PUT and DELETE operations.  For example, consider our image example from before.  We can read the image by doing:

GET http://myserver/myphotos/mywedding.img


We can replace the image by doing:

PUT http://myserver/myphotos/mywedding.img

Note that this operation would succeed regardless if the resource existed before or not, because the photo album resource allows for generic nested resources.


And we can delete the image by doing:

DELETE http://myserver/myphotos/mywedding.img


The entity pattern also applies to resources with sub-structure that are accessible as nested resources.  For example, consider an entry in an address book.  We can retrieve the entry in its entirety by doing a GET operation on it:

GET http://myserver/myaddressbook/johndoe


We can also update individual properties of the entry, because they are exposed as nested resources.  For example, to change the work phone number, we can do a PUT operation on the corresponding resource:

PUT http://myserver/myaddressbook/johndoe/workphone

Note that this operation would succeed regardless if the resource existed before or not, because the contact resource allows for a nested resource of this name.


Similarly, we can remove a property by doing a DELETE operation on its resource:

DELETE http://myserver/myaddressbook/johndoe/homephone


An entity may have nested resources, but these nested resources are either generic, as is the case in our photo album example, or they are predefined, as is the case in our contact example.  In both cases, no algorithm was required to divine what the nested resource's name would be.  Also note that a nested resource of an entity does not have to be an entity too.  A nested resource can be anything it wants or needs to be.


An entity resource has the following pattern:

Verb Resource Meaning
GET /resource Retrieve the entire resource.  Query parameters may be available to retrieve only parts of the resource.
PUT /resource Replace the entire resource and all nested resources.
DELETE /resource Delete the entire resource and all nested resources.
GET /resource/nested (optional) Retrieve the entire nested resource.  Query parameters may be available to retrieve only parts of the nested resource.
PUT /resource/nested (optional) Replace or create the entire nested resource and all its nested resources.
DELETE /resource/nested (optional) Delete the entire nested resource and all its nested resources.
* /resource/nested (optional) Additional verbs may be supported by the nested resource.

Container Pattern

The container pattern builds on the entity pattern by providing the means to dynamically add and/or update nested resources.  For example, in the case of our blog resource, we could not reliably determine the name of the blog post resource, because of race conditions.  In this case, we need to use a POST operation to add the nested resource.

POST http://myserver/myblog

A contents of the POST request must contain enough information about the intended operation to be carried out.  For example, it might be used to add one or more nested resources.  Regardless of specifics, the POST operation can only affect the resource and its nested resources.


When a nested resource is created, the POST response should contain the location of the new resource.  Also, if the POST operation can modify the resource before creating it, it should include the updated resource in its response.


The Atom Publishing Protocol is an excellent example of applying the container pattern to create a blogging application interface.


A container resource has the following pattern:

Verb Resource Meaning
GET /resource Retrieve the entire resource.  Query parameters may be available to retrieve only parts of the resource.
PUT /resource Replace the entire resource and all nested resources.
DELETE /resource Delete the entire resource and all nested resources.
POST /resource Creates a nested resource.
GET /resource/nested (optional) Retrieve the entire nested resource.  Query parameters may be available to retrieve only parts of the nested resource.
PUT /resource/nested (optional) Replace or create the entire nested resource and all its nested resources.
DELETE /resource/nested (optional) Delete the entire nested resource and all its nested resources.
* /resource/nested (optional) Additional verbs may be supported by the nested resource.

Behavior Pattern

The behavior pattern applies to resources that carry out operations.  These resources have generally no state of their own and only support the POST operation.  They may be a nested resource of an entity or container resource, which they may affect.  This is in stark contrast to the POST operation on container resources which only affects the resource itself and its nested resources.  Indeed, behavior resources have great latitude in impacting the overall state of a system.


Some behavior resources support the GET operation to return a HTML form that can be used to fill in the arguments for the POST operation.


Behavior resources never have nested resources.  They are always leaf terms of the servers resource tree.


A behavior resource has the following pattern:


Verb Resource Meaning
GET /resource (optional) Retrieve a form to submit the arguments for the operation.
POST /resource Carry out an operation.

Conclusion

The REST architecture style builds on the foundation of what has made world wide web such a scalable platform.  It is quickly gaining in momentum because it is so easy to use.  But at the same time, it's novelty comes also with new design challenges. This introduction has shown how the basic HTTP verbs GET, PUT, DELETE, POST can be composed into regular patterns that can be applied to various situations.  Following these patterns will make it easier for others to quickly understand your services and to write new services that integrate well.

    

The list of patterns on this page is just a beginning.  More can and need to be defined.  This site is a wiki, meaning you can add and improve on it.  Just create an account, click edit, and help define what these patterns should look like or post your feedback in the discussion forums.

Tag page
Viewing 1 of 1 comments: view all
The Atom Publishing Protocol link is stale. I found this though http://www.ietf.org/rfc/rfc5023.txt. Does it relate to the one that was originally on this page?
Posted 09:31, 30 Jan 2008
Viewing 1 of 1 comments: view all
You must login to post a comment.
Powered by MindTouch Deki v.8.08.2