





















































This article by Bhakti Mehta, the author of Restful Java Patterns and Best Practices, starts with the basic concepts of REST, how to design RESTful services, and best practices around designing REST resources. It also covers the architectural aspects of REST.
(For more resources related to this topic, see here.)
The confluence of social networking, cloud computing, and era of mobile applications creates a generation of emerging technologies that allow different networked devices to communicate with each other over the Internet. In the past, there were traditional and proprietary approaches for building solutions encompassing different devices and components communicating with each other over a non-reliable network or through the Internet. Some of these approaches such as RPC, CORBA, and SOAP-based web services, which evolved as different implementations for Service Oriented Architecture (SOA) required a tighter coupling between components along with greater complexities in integration.
As the technology landscape evolves, today’s applications are built on the notion of producing and consuming APIs instead of using web frameworks that invoke services and produce web pages. This requirement enforces the need for easier exchange of information between distributed services along with predictable, robust, well-defined interfaces. API based architecture enables agile development, easier adoption and prevalence, scale and integration with applications within and outside the enterprise
HTTP 1.1 is defined in RFC 2616, and is ubiquitously used as the standard protocol for distributed, collaborative and hypermedia information systems. Representational State Transfer (REST) is inspired by HTTP and can be used wherever HTTP is used.
The widespread adoption of REST and JSON opens up the possibilities of applications incorporating and leveraging functionality from other applications as needed. Popularity of REST is mainly because it enables building lightweight, simple, cost-effective modular interfaces, which can be consumed by a variety of clients. This article covers the following topics
REST is an architectural style that conforms to the Web Standards like using HTTP verbs and URIs. It is bound by the following principles.
REST is extensible due to the use of URIs for identifying resources.
For example, a URI to represent a collection of book resources could look like this:
http://foo.api.com/v1/library/books
A URI to represent a single book identified by its ISBN could be as follows:
http://foo.api.com/v1/library/books/isbn/12345678
A URI to represent a coffee order resource could be as follows:
http://bar.api.com/v1/coffees/orders/1234
A user in a system can be represented like this:
http://some.api.com/v1/user
A URI to represent all the book orders for a user could be:
http://bar.api.com/v1/user/5034/book/orders
All the preceding samples show a clear readable pattern, which can be interpreted by the client. All these resources could have multiple representations.
These resource examples shown here can be represented by JSON or XML and can be manipulated by HTTP methods: GET, PUT, POST, and DELETE.
The following table summarizes HTTP Methods and descriptions for the actions taken on the resource with a simple example of a collection of books in a library.
HTTP method | Resource URI | Description |
GET | /library/books | Gets a list of books |
GET | /library/books/isbn/12345678 | Gets a book identified by ISBN “12345678” |
POST | /library/books | Creates a new book order |
DELETE | /library/books/isbn/12345678 | Deletes a book identified by ISBN “12345678” |
PUT | /library/books/isbn/12345678 | Updates a specific book identified by ISBN “12345678’ |
PATCH | /library/books/isbn/12345678 | Can be used to do partial update for a book identified by ISBN “12345678” |
REST is bound by the principle of statelessness. Each request from the client to the server must have all the details to understand the request. This helps to improve visibility, reliability and scalability for requests.
Visibility is improved, as the system monitoring the requests does not have to look beyond one request to get details. Reliability is improved, as there is no check-pointing/resuming to be done in case of partial failures. Scalability is improved, as the number of requests that can be processed is increases as the server is not responsible for storing any state.
Roy Fielding’s dissertation on the REST architectural style provides details on the statelessness of REST, check http://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm
With this initial introduction to basics of REST, we shall cover the different maturity levels and how REST falls in it in the following section.
Richardson maturity model is a model, which is developed by Leonard Richardson. It talks about the basics of REST in terms of resources, verbs and hypermedia controls. The starting point for the maturity model is to use HTTP layer as the transport.
This level contains SOAP or XML-RPC sending data as POX (Plain Old XML). Only POST methods are used. This is the most primitive way of building SOA applications with a single method POST and using XML to communicate between services.
This uses POST methods and instead of using a function and passing arguments uses the REST URIs. So it still uses only one HTTP method. It is better than Level 0 that it breaks a complex functionality into multiple resources with one method.
This level uses other HTTP verbs like GET, HEAD, DELETE, PUT along with POST methods. Level 2 is the real use case of REST, which advocates using different verbs based on the HTTP request methods and the system can have multiple resources.
Hypermedia as the Engine of Application State (HATEOAS) is the most mature level of Richardson’s model. The responses to the client requests, contains hypermedia controls, which can help the client decide what the next action they can take. Level 3 encourages easy discoverability and makes it easy for the responses to be self- explanatory.
This section discusses in details about what are safe and idempotent methods.
Safe methods are methods that do not change the state on the server. GET and HEAD are safe methods.
For example GET /v1/coffees/orders/1234 is a safe method.
Safe methods can be cached.
PUT method is not safe as it will create or modify a resource on the server. POST method is not safe for the same reasons. DELETE method is not safe as it deletes a resource on the server.
An idempotent method is a method that will produce the same results irrespective of how many times it is called.
For example GET method is idempotent, as multiple calls to the GET resource will always return the same response.
PUT method is idempotent as calling PUT method multiple times will update the same resource and not change the outcome.
POST is not idempotent and calling POST method multiple times can have different results and will result in creating new resources. DELETE is idempotent because once the resource is deleted it is gone and calling the method multiple times will not change the outcome.
HTTP verbs inform the server what to do with the data sent as part of the URL
GET is the simplest verb of HTTP, which enables to get access to a resource. Whenever the client clicks a URL in the browser it sends a GET request to the address specified by the URL. GET is safe and idempotent. GET requests are cached. Query parameters can be used in GET requests.
For example a simple GET request is as follows:
curl http://api.foo.com/v1/user/12345
POST is used to create a resource. POST requests are neither idempotent nor safe. Multiple invocations of the POST requests can create multiple resources.
POST requests should invalidate a cache entry if exists. Query parameters with POST requests are not encouraged
For example a POST request to create a user can be
curl –X POST -d’{“name”:”John Doe”,“username”:”jdoe”, “phone”:”412-344-5644”}
http://api.foo.com/v1/user
PUT is used to update a resource. PUT is idempotent but not safe. Multiple invocations of PUT requests should produce the same results by updating the resource.
PUT requests should invalidate the cache entry if exists.
For example a PUT request to update a user can be
curl –X PUT -d’{ “phone”:”413-344-5644”}
http://api.foo.com/v1/user
DELETE is used to delete a resource. DELETE is idempotent but not safe. DELETE is idempotent because based on the RFC 2616 "the side effects of N > 0 requests is the same as for a single request". This means once the resource is deleted calling DELETE multiple times will get the same response.
For example, a request to delete a user is as follows:
curl –X DELETE http://foo.api.com/v1/user/1234
HEAD is similar like GET request. The difference is that only HTTP headers are returned and no content is returned. HEAD is idempotent and safe.
For example, a request to send HEAD request with curl is as follows:
curl –X HEAD http://foo.api.com/v1/user
It can be useful to send a HEAD request to see if the resource has changed before trying to get a large representation using a GET request.
According to RFC the difference between PUT and POST is in the Request URI. The URI identified by POST defines the entity that will handle the POST request. The URI in the PUT request includes the entity in the request.
So POST /v1/coffees/orders means to create a new resource and return an identifier to describe the resource
In contrast PUT /v1/coffees/orders/1234 means to update a resource identified by “1234” if it does not exist else create a new order and use the URI orders/1234 to identify it.
This section highlights some of the best practices when designing RESTful resources:
This section will cover the various components that must be considered when building RESTful APIs
As seen in the preceding screenshot, REST services can be consumed from a variety of clients and applications running on different platforms and devices like mobile devices, web browsers etc.
These requests are sent through a proxy server. The HTTP requests will be sent to the resources and based on the various CRUD operations the right HTTP method will be selected. On the response side there can be Pagination, to ensure the server sends a subset of results. Also the server can do Asynchronous processing thus improving responsiveness and scale. There can be links in the response, which deals with HATEOAS.
Here is a summary of the various REST architectural components:
The REST Architectural components in the image can be chained one after the other as shown priorly. For example, there can be a filter chain, consisting of filters related with Authentication, Rate limiting, Caching, and Logging. This will take care of authenticating the user, checking if the requests from the client are within rate limits, then a caching filter which can check if the request can be served from the cache respectively. This can be followed by a logging filter, which can log the details of the request. For more details, check RESTful Patterns and best practices.