Best practices for better RESTful Web Services


Nowadays the use of REST web services is essential in the development of web applications, APIs creation, etc. One of the most common mistakes on the design of this kind of applications comes when a developer is not aware of the best practices that should be followed, and, as a consequence the application turns to be messy, hard to use and understand.

On this post we will mention some of the best practices used to create REST web services.

To be ALWAYS STATELESS:

The first rule when managing REST web services is to design them 100% STATELESS, meaning this that each request done by some client should be independent from the previous one.

Stateless web services allows the application to be easily scalable avoiding the migration of user sessions from one cluster to the new ones, you just need to put a load balancer and a new instance of the application and you can be sure that every single request will be processed (as long as this is a correct request!).

Use nouns, not verbs:

Not to do:

Method: GET     Endpoint: /getUsers/

Description: Returns a list of users.

You should always use nouns instead of verbs, when a developer use verbs the endpoint turns to be redundant since it is already defined on the HTTP method.

The correct way to define the previous endpoint is the following:

Method: GET     Endpoint: /users/

Description: Returns a list of users.

This example is using an HTTP GET method and the /users/ endpoint which sounds logic and its purpose is easy to understand.

If you need to get just one user, the correct way to handle this is the following:

Method: GET     Endpoint: /users/123

Description: Returns a user with the specified ID.

As you can see, there is no need for verbs on any endpoint since the /users/{id} endpoint is easy to understand.

Some examples of common mistakes are:

/getUsers  /updateUser      /deleteUser

Use the correct HTTP method

A common mistake on many REST APIs is that most of their web services are usually GET and POST. Here you have a list of the available HTTP methods, their use and some common responses to those

  • GET: Returns one or many resources according to the consumed endpoint, the most common response is a JSON with the requested object or objects.
  • POST: Creates a new resource, a good practice is to return a link to the created resource. For more details you can review the following section about HATEOAS.
  • PUT: Updates an already created resource, a good practice is to return a link to the created resource. For more details you can review the following section about HATEOAS.
  • PATCH: Partially updates an existent resource, a good practice is to return a link to the created resource. For more details you can review the following section about HATEOAS.
  • DELETE: Deletes a resource, a good practice is to return a 204 HTTP status (Not content) to confirm that the resource has been deleted successfully.

On the next paragraphs we will explain on detail the most common HTTP status and when to use those.

Allow HTTP methods to be overridden

Some HTTP clients can only work using GET and POST requests; this is why it is necessary to allow method overrides (X-HTTP-Method-Override, allowing the override from a POST to a PUT, PATCH or DELETE request. This is only used to change the behavior of the POST method; GET should never modify any resource from the server.

Correct use of HTTP methods

If your web services are returning an HTTP 200 status for every kind of request (correct or incorrect), and equally sending HTTP 500 status on every error, you will be facing several issues trying to identify the piece that is failing in your server due to the poor information given by those HTTP status. On the next lines you will find the uses of each range of HTTP status:

  • 1xx (100 – 199): Informational status.
  • 2xx (200-299): Successful status, some responses of this range are: 200 (OK) meaning successful request or 201 (Not content) meaning that a resource has been successfully deleted.
  • 3xx (300-399): Redirection, this response indicates that there is a missing step to finish the request so a redirection will be tried to get it.
  • 4xx (400-499): Client side error. It is common to return always an HTTP 400 status for different kind of errors. The correct way to use it is to identify if the error was due to something in the client or server sides. For example, an HTTP 404 response occurs when a client is trying to retrieve a non-existent resource. An HTTP 403 status occurs when a client does not have access to retrieve a specific resource.
  • 5xx (500-599): Server side error. Similarly to the previous status, the developer should be aware of the origin of an error if this error comes from the client or the server. These kinds of errors are related to something wrong on the server for example a bad connection with a DB.

If for every request your REST web services are returning a correct status, the client will be able to understand and handle any error in the best way. Here you have an example of an endpoint with each of its possible responses.

Method: GET       Endpoint: /users/123

Description: Returns a user with the specified ID.

Responses:

  • HTTP 200: The user exists and the client has access to this resource. It will return a JSON file with the requestd data.
  • HTTP 404: The requested user does not exist. This will return a JSON file with an error message.
  • HTTP 403: The client has been authenticated but it is not authorized to get the specified resource. A JDSON file with the error message will be returned.

Use HATEOAS (Hypermedia as Engine of Application State)

Use HATEOS provides a great user experience when working with an API allowing it to understand each web service without using any kind of documentation. You can review an example of this tool on the following post: Spring Boot + REST Jersey (Using Spring Hateoas and DTO) part 3.

Use only SSL for all your requests

Many users use to connect their application using public networks on streets that can be easily eavesdropped by anyone, due to cases like this it is required for all the requests to be processed through an SSL connection.

API Documentation

Documenting a REST API is not as complex and tedious as it was a few years ago, nowadays you can find different tools that are used to generate documentation emulate requests and also generate code snippets for the clients to be used in different programming languages. Good recommendations of this kind of tools are https://apiary.io/ or https://swagger.io/.

Be careful when to use REST

Nowadays many people use RESTful web services for everything, but not all the cases require a RESTful web service, if the application has it’s own database (And this application is the only one that uses the database)  you can just create a connection to the database and that is all.

Pagination

There are endpoints that can return a big quantity of records which sometimes is hard to handle due to the available resources on the client side and also in the server side. The following code snippet illustrates how to use pagination inside a GET request:

GET /tweets?offset=20&limit=10

Versioning your API

You should never run an API without a version since there will be moments where it is going to be necessary to modify the behavior of some web service, for this, it is better to have different versions so you can be sure you are using the recently updated code. There are many ways to do versioning and it is very controversial in the industry here the following are some available options to do versioning in an api:

  • URL Versioning:  
    HTTP GET: /application/api/v1
  • Adding a custom header in the request:  
    HTTP GET: /application/api/v1  api-version: 1
  • Media type versioning:
    HTTP GET :  /application/api/v1
    Accept: application/raidentrance.api.v2+json
  • Domain versioning
    HTTP GET :  apiv1.geeks-mexico.com/application/api/v1
    Accept: application/raidentrance.api.v2+json
  • Request parameter versioning
    HTTP GET : /application/api/v1/users/?version=1

Authentication

As we mentioned before, a REST API must be Stateless, meaning that every request should be sent to an Authentication mechanism such as OAuth 2 (you can find more information here). This kind of requests has to be managed using an SSL connection.

Always use a lightweight framework

Nowadays REST web services are widely used in different architectures of micro services where just simple tasks are going to be executed. This is why it is better to work with lightweight environments giving a simple way to build and code applications.

The practices presented in this post are language-independent since any REST API can follow them.

If you want to learn more about web services we recommend the following books:

Author: Alejandro Agapito Bautista

Twitter: @raidentrance

Contact:raidentrance@gmail.com

Translated By: Oscar Camacho – melchior01

Contact: adamfirstangel@hotmail.com

Anuncios

2 Comentarios »

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión /  Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión /  Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión /  Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión /  Cambiar )

Conectando a %s