Saturday, January 19, 2019

REST (Representational State Transfer) : Key Concepts and Best Practices

In this post I will explain key concepts and best Practices about REST, Representational State Transfer, abbreviated as REST, is not a technology, a library, nor an architecture, but a model to be used for designing distributed software architectures based on network communication.


REST is one of the main models that has been described by Roy Fielding, one of the main creators of the HTTP protocol, in his PhD thesis and adopted as the model to be used in the evolution of the HTTP protocol architecture.
Many developers realized that they could also use the REST model to deploy Web Services to integrate applications over the Web and started using it as an alternative to SOAP .
REST can actually be considered as a set of principles, which when applied correctly in an application, benefits it with the architecture and standards of the Web itself.
Let us now look at these principles and how to use them correctly.

Identification of Resources

Every application manages some information. An application of an E-commerce, for example, manages its products, clients, sales, etc. These things an application manages are called Resources in the REST model.

A resource is nothing more than an abstraction about a certain type of information that an application manages, and one of the principles of REST says that every resource must have a unique identification. This identification is for the application to be able to differentiate which of the resources must be manipulated in a given request.

Imagine the following situation: You have developed a REST Web Service that manages six types of resources. Customers of this Web Service manipulate these resources via HTTP requests. When a request for the Web Service arrives, how will it know which of the features should be handled? It is precisely for this reason that resources must have a unique identification, which must be informed in the requisitions.

The identification of the resource should be done using the concept of Uniform Resource Identifier (URI), which is one of the standards used by the Web. Some examples of URI's:

  • http://servicerest.com.sg/products;
  • http://servicerest.com.sg/clients;
  • http://servicerest.com.sg/clients/57;
  • http://servicerest.com.sg/sales

URIs are the user interface of your services and work as a contract that will be used by customers to access them. Let us now look at some good practices in using URIs.

Use Readable URIs


When defining a URI, use human-readable names that are easy to deduce and that are related to the application domain. This makes life easier for customers who will use the service, and reduces the need for extensive documentation.


Use the same URI standard in resource identification

Maintain consistency in the definition of URIs. Create a naming pattern for the resource's URIs and always use the same pattern. Avoid situations like:
  • http://servicerest.com.sg/produt (Singular)
  • http://servicerest.com.sg/clients (Plural)
  • http://servicerest.com.sg/AdministrativeProcesses (Camel Case)
  • http://servicerest.com.sg/legal_processes (Snake Case)

Avoid adding to the URI the operation to be performed on the resource

The resources that an application manages can be manipulated in several ways, being made available some operations to manipulate them, such as: create, list, delete, update, etc.
The manipulation of resources must be done using the HTTP protocol methods, which is also one of the REST principles that will be discussed later.
Therefore, avoid defining URI's that contain the operation to be performed on a resource, such as:
  • http://servicerest.com.sg/products/cada
  • http://servicerest.com.sg/clients/10/exclude
  • http://servicerest.com.sg/sales/34/upualizar

Avoid adding the desired format of the resource representation in the URI

It is common for a REST service to support multiple formats to represent its resources, such as XML, JSON, and HTML. Information on what format a client wants to query a REST service should be done via Content Negotiation, as will be shown below.
Therefore, avoid defining URI's that contain the desired format of a resource, such as:
  • http://servicerest.com.sg/produts/xml
  • http://servicerest.com.sg/clients/112?format=json

Avoid changes in URIs

The URI is the gateway to a service. If you change it, this will certainly impact the customers you were using because you changed the way you access it. After you set a URI and make a resource manipulated by it, avoid making changes to it.
In the most critical cases, where a URI will actually need to be changed, notify the clients of that service in advance. Also check the possibility of keeping the old URI by making a redirect to the new URI.

Using HTTP methods to manipulate resources

IFeatures managed by an application, and identified only through its URI, can often be handled in a variety of ways. You can create, update, delete them, and other operations.
When a client triggers an HTTP request for a service, in addition to the URI that identifies which features it intends to handle, it must also inform the type of handling that it wants to perform on the resource. It is precisely here that another concept of the Web comes in, which are the methods of the HTTP protocol.
The HTTP protocol has several methods, each of which has a distinct semantics, and must be used to indicate the type of manipulation to be performed in a given resource.
Let's look now at the main HTTP protocol methods and the usage scenario for each of them:

GETRetrieve the data of a resource.
POSTCreate a new resource.
PUTReplace the data for a given resource.
PATCHPartially update a particular feature.
DELETEDelete a certain resource.
HEADSimilar to GET, but used only to get the response headers, without the data itself.
OPTIONSObtain which manipulations can be performed on a given resource.

Applications generally only use the GET, POST, PUT, and DELETE methods, but if it makes sense in your application to use any of the other methods, there is no problem with that.
The following is the pattern of using HTTP methods in a REST service, which is used by most applications and can be considered good practice. As an example, a feature called Client will be used.

MethodURIUse
GET/customersRecover data from all clients.
GET/ clients / idRecover data from a particular client.
POST/customersCreate a new client.
PUT/ clients / idUpdate the data of a particular client.
DELETE/ clients / idDelete a particular client.
As a good practice, with regard to HTTP protocol methods, avoid using only the POST method on requests that change the state on the server, such as: registration, change and deletion, and above all, avoid using the GET method in these types of operations, since browsers often cache GET requests, firing them before the user clicks on buttons and links in an HTML page.

Representations of resources

The resources are stored by the application that manages them. When requested by client applications, for example in a GET request, they do not "abandon" the server, as if they had been transferred to clients. In fact, what is transferred to the client application is just a representation of the resource.
A resource can be represented in several ways, using specific formats such as XML, JSON, HTML, CSV, among others. Example of representation of a resource in XML format.

  Pradeep
  pradeep@gmail.com
  Masculino
  
Orchard Senkang
Communication between applications is done by transferring representations of the resources to be manipulated. A representation can also be considered as the indication of the current state of a given resource.
This communication made through the transfer of representations of the resources generates a decoupling between the client and the server, something that greatly facilitates the maintenance of the applications.

Support different representations

It is considered good practice to support multiple representations in a REST service, as this facilitates the inclusion of new clients. By supporting only one type of format, a REST service limits its clients, who must adapt to be able to communicate with it.
The three major formats supported by most REST services are:
  • HTML
  • XML
  • JSON

Use Content Negotiation to support multiple representations

When a REST service supports more than one format for the representations of its resources, it is common for it to expect the client to provide the information of which format it wants. In REST, this negotiation of the resource representation format is called Content Negotiation and in the Web world it must be done via an HTTP header, known as accept.
When making a call to the REST service, a client can add the accept header to the request to indicate to the server the desired format of the resource representation. Of course, it must be a format that is supported by the REST service.

Stateless Communication

The Web is the main system that uses the REST model. Today it supports billions of connected clients and exchanging information. But how is it possible for the Web to have such good scalability and performance that it can handle so many customers?
The Answer: Stateless Communication!
Requests made by a client to a REST service must contain all the information necessary for the server to interpret and execute them correctly. Clients should not rely on data previously stored on the server to process a request. Any status information must be maintained by the client and not by the server. This reduces the need for large amounts of physical resources, such as memory and disk, and also improves the scalability of a REST service.

It is precisely because of this feature that the Web can achieve virtually infinite scalability, since it does not have to maintain the state information of each client.
This is one of the most difficult principles to apply in a REST service, since it is very common for applications to maintain state between client requests. An example of this is when we need to store the data of users who are authenticated in the application.

Avoid keeping authentication / authorization data in session

The main difficulty in creating a fully Stateless REST service occurs when we need to deal with customer authentication / authorization data. The difficulty arises because it is natural for developers to store such information in session, as this is the common solution when developing a traditional Web application.
The main solution used to solve this problem is the use of access tokens, which are generated by the REST service and must be stored by clients, via cookies or HTML 5 Web Storage, and should also be sent by clients with each new request to the service.
There are already several technologies and standards to work with Tokens, among them:
  • OAUTH
  • JWT (JSON Web Token)
  • Keycloack

HATEOAS (Hypermedia As The Engine Of Application State)

To better understand the concept of HATEOAS, let's take a common example when using the Web.
Imagine that you want to buy a product through the Web at some E-commerce site. You enter the site, navigate through the product categories via the menu of the site, find your product and get to the details screen of it, which has the price information, shipping and the button to make the purchase.
But not always the product is available in stock, so the site usually treat in this situation, hiding the button to make the purchase and displaying a button for notification when the product is again available.
In the previous example, the concept of HATEOAS was applied twice. First, when the customer entered the E-commerce site, how did he get to the product detail page? Browsing via links.
Usually every site or Web application has several features, and navigation between them is usually done via links. A customer may even know the URI of a given page or resource, but if he does not know we need to guide him in some way so that he can find the information he's looking for.
The second use of HATEOAS occurred when the customer accessed the product details page. If the product was in stock, the site would display the buy button, and the customer could finalize your order. Otherwise, it could just register to be notified. All this is mainly done to ensure the consistency of the information.
Notice that the links were used as a mechanism to guide the client regarding navigation and the state of the resources. This is the concept that was called HATEOAS, which is nothing more than the use of Hypermedia, with the use of links, as the engine to guide customers as to the current state of the resources, and also the state transitions that are currently available.
Here's an example of a representation of a resource without the use of the HATEOAS concept:

  1459
  2019-01-25
  PENDING
  
    David
  

In the previous example the representation of the resource "Request" in the XML format, containing its information, but without the use of HATEOAS was presented. This can certainly generate some doubts for customers of this REST service, such as:
  • Is it possible to request cancellation of the order? As?
  • What are the other statuses of the application and how do they go through them?
  • How can I get more information about the customer for this order?
These doubts could be easily answered if the HATEOAS concept was used, thus facilitating the life of REST service customers. Let us now see the same representation, but with the use of HATEOAS:

  1459
  2019-01-25
  PENDING
  
  
    
      self
      http://servicerest.com.sg/products/1459
      GET
    
    
      cancel
      http://servicerest.com.sg/products/1459
      DELETE
    
  

Notice how much simpler it has now been to explore the information and find out which paths to follow. HATEOAS is one of the principles that we hardly see being applied in REST services in the market, almost always for lack of knowledge of the developers.

Correct use of HTTP codes

In the HTTP protocol, every request made by a client to a server must result in a response, in which there is an HTTP code, used to inform the result of the request, whether it has been successfully processed or not.
There are dozens of HTTP codes, each having its own semantics and should be used when it makes sense. HTTP codes are grouped into classes, as shown below:

ClassSemantics
2xxIndicates that the request has been processed successfully.
3xxIt indicates to the client an action to be taken so that the request can be completed.
4xxIndicates error (s) in the request caused by the client.
5xxIndicates that the request was not completed due to error (s) occurred on the server.
The best practice is to know the main HTTP codes and use them correctly. See the main HTTP codes and when to use them:

CodedescriptionWhen to use
200OKIn GET, PUT, and DELETE requests executed successfully.
201CreatedIn POST requests, when a new resource is created successfully.
206Partial ContentIn GET requests that return only part of the content of a resource.
302FoundIn requests made to the old URIs, they were changed.
400Bad RequestIn requests whose information sent by the client is invalid.
401UnauthorizedIn requests that require authentication, but their data was not provided.
403ForbiddenIn requests that the client is not allowed access to the requested resource.
404Not FoundIn requests whose URI for a particular resource is invalid.
405Method Not AllowedIn requests whose client-specified HTTP method is not supported.
406Not AcceptableIn requests whose format of the resource representation requested by the client is not supported.
415Unsupported Media TypeIn requests whose format of the resource representation sent by the client is not supported.
429Too Many RequestsIn case the service has a limit of requests that can be made by a client, and it has already been reached.
500Internal Server ErrorIn requests where an error has occurred on the server.
503Service UnavailableIn requests made to a service that is out of the air, for maintenance or overload.

Conclusion

REST is not a seven-headed animal. It has only a few principles and restrictions that must be used to guarantee some important features in applications and services, such as portability, scalability and decoupling.
The Web is the main example of implementing the REST model, and we should mirror it when building our services following the same model.
TAll of the REST model concepts described in this post can also be used in the implementation of Web applications, not only in the case of systems integration via Web Services.
Even if you use these concepts in a traditional Web application, and one day it needs to become a REST API, the impact of the changes will be minimal because your application will already be following REST principles. What will change is that now instead of returning only HTML pages to clients it can also return the resource information in some format, such as JSON, and the client is going to worry about how to format them.
When an application or service follows the principles outlined in this article, it is called RESTful. Some purists consider just as RESTful the application or service that follow all the principles of REST, including the least used such as Stateless communication and HATEOAS.
But do not focus on being RESTful or not, but on trying to use as much REST principles as possible so that your application or service gets all the benefits of that model.