REST: Uniform interface

In the previous post REST architecture style was discussed, one of the pillars of which is the uniform interface which is the topic of the current post. While REST is not limited by a particular protocol, HTTP is the protocol which is used to implement RESTful applications  in day-to-day life, so the discussion below will be based on HTTP. What the REST puts a constraint on is the interface, in other words, interaction and implementation details are guided by a set of rules.

The constraints on the service interface in order to be called REST as described in the Dr. Roy Fielding’s thesis are:
  • identification of resources;
  • manipulation of resources through representations;
  • self-descriptive messages;
  • hypermedia as the engine of application state.

World Wide Web widely uses three technologies - hypermedia, HTTP and URI - which can be be adopted for creation of Web services or APIs in modern jargon. Not every service or API  that relies on HTTP protocol can be called RESTFul, another term meaning “based on REST architecture principles”. For example, a typical SOAP Web service uses a single URI and single HTTP method for several resources, so each resource is not identified by its own URL and such a service is not RESTful.

In order to simplify application of the constraints to REST interface design, those were broken down into four levels of maturity by Leonard Richardson in his 2008 QCon talk and later spelled out by Martin Fowler using a term Richardson Maturity Model  (RMM).

Long story short, the aforementioned SOAP Web service which uses only one URI and a single HTTP method is at Level 0 of Richardson Maturity Model. At Level 1 of RMM services use several URIs, each to identify an individual resource, but a single HTTP method to drive the application state.

Take, for example, a simple To-do list service. Each registered user should be able to browse lists of tasks, such as home, work etc. and browse tasks in these lists as well. It is possible to access a work task list using a following URI.

/user/jsmith/tasklist/work,

while the enumeration of all tasks could be obtained using a part of the above URI.

/user/jsmith/tasklist

To gain access to all the tasks in a particular list, work in the example below, one should use a URI

/user/jsmith/tasklist/work/tasks,

and a single task could be accessed using
/user/jsmith/tasklist/work/tasks/3,

where 3 is an identifier of the task.

At level two HTTP methods, such as DELETE, GET, POST and PUT, come into play, moreover,  their semantics should be the same as in HTTP specification RFC 2616. This means that GET is used only for operations that do not change resources. In our running example GET could be used to obtain a representation of the task number 3 in the work list

GET /user/jsmith/tasklist/work/tasks/3

or to get a list of all tasks

GET /user/jsmith/tasklist/work/tasks

On the other hand, to add a new resource one could use POST method, for example a request

POST  /user/jsmith/tasklist/work/tasks

with all the necessary data pertaining to a task in its body adds a new task to the work list. As it can be easily guessed, to delete a task the DELETE verb should be used with an URI containing the identifier of a task.

DELETE  /user/jsmith/tasklist/work/tasks/3

The complete description of all HTTP methods used in conjunction with RESTful services and their usage patterns is out of scope of this post, the latter is intended only to give a brief introduction to the topic. The benefit of using such methods is that the same methods are applied to complete the same actions to the resource, be it a task or a task list. In addition, HTTP response codes are widely used to inform the user of a service about the result of an operation, which is a topic of a separate post.

Level 3 deals with what essential parts representations should contain. In a nutshell, a developer of a client shouldn’t have any knowledge of all the resources beforehand. All she should know is the address of a service. For example, if an authenticated user of a service is directed to a URL
www.example.com/user/jsmith, the response should contain among other things hyperlinks describing possible actions of the user at the current state of the application, such as

<link rel = “/rel/add-tasklist” href=”/user/jsmith/tasklist”/>

for XML representation and

“link” : {
    “rel” : “/rel/add-tasklist”,
    “href” : ”/user/jsmith/tasklist”
}

for a JSON one.

The href attribute is a URL of the resource and the second attribute, rel, shows an operation which could be performed on the resource. The format of the second attribute is a URI and, firstly, an operation name in a human readable format is a part it, secondly, it is advisable that when navigating to the resource identified by the aforementioned URI there should be a human-readable instructions describing how to deal with the operation. So, by following the link above the client of the To-do list API is able to add a new task list. What method to use is described at Level two of Richardson maturity model.

The idea is that a developer of the client learns what are the possible operations of a particular API by peeking at links at each step, so that the API is self-documented and if the address of a resource changes, no changes in the client are necessary due to the fact that no URI were hard-coded in it. All the information about possible future steps is a part of a current representation. No references to documentation, also referred as out-of-band information because it is not a part of a representation, are necessary.

Other possible operations could include listing of all task lists as well as an option to delete all task lists. The state of an application is changed by following the links which means that REST services or APIs are hypermedia driven, a concept called by the author of the REST architectural style Hypermedia As The Engine Of An Application state(HATEOAS).

Another example of using hyperlinks in a representation of a resource could be the content of a particular task list. Such list, except all the tasks in it, at level 3 of RMM should also contain the reference to itself, also each task should contain a link referencing to itself besides the task data such as the name, priority and the due date. In addition, if only a part of a list is served by an API to streamline client’s performance, for instance using pages of ten tasks each, links to the neighboring pages should be provided. If a user is on a page three, links addressing pages two and four should be added to the representation in order for the client to be able to change the state of the application. A statelessness of the server is achieved in this way. One more possible candidate is a link, enabling the client to add a task.

Further reading:

Comments

Popular posts from this blog

Bootstrap 3 Forms Tutorial

Spring Tutorial: Creating a Hello World REST API Using Spring Framework and Spring Boot

Getting started with Dropwizard: First steps