REST services

The purpose of the article is not to define REST. It is focused on people who already know it but are not very clear about some good practices to consider.

Use two URLs to get a resource

When obtaining resources, it is advisable to have two GET type methods. The first would be to obtain the entire collection and the second to obtain an element by its identifier.

Suppose we have a model called cars, we should have the following URLs:

GET /api/v1/cars
GET /api/v1/cars/:id

Add, update, delete
In the previous step we have seen how to get one or all of the cars. Now let’s see how to add, update or delete a car.

HTTP has its methods that allow you to call the same URL with different method so we can do the following:

GET    /api/v1/cars
GET    /api/v1/cars/:id
POST   /api/v1/cars
PUT    /api/v1/cars/:id
DELETE /api/v1/cars/:id

Filter results

Now that we are know about the basic structure of the URLs, it is time to move on to other more specific details, let us suppose now that we want to filter cars with a certain characteristic, for example that their color is blue and that it is 2 years old. Our query would be more or less like this:

GET /api/v1/cars?color=blue&age=2

HTTP Status Codes
It is good to make use of the status codes provided by HTTP, with them we will be able to indicate the result of our operation, if it was successful, if it failed, if we are not authorized, etc….

As a general rule it will be met the follow:

  • Codes 2XX were successful.
  • Codes 3XX redirections and others.
  • Codes 4XX there was client error.
  • Codes 5XX there was server error.

Give information to the client

The same error code can occur for several cases of use, it is therefore advisable to accompany the response with a message detailing the output, and it is also advisable to use an internal error code system so that a list of references can be consulted.

HTTP STATUS 400 (Bad Request)
{
    "success"  : false,
    "message"  : "Negative values are not allowed.",
    "errorCode": 11857
    "data"     : null
}

Pagination

Through the operators “? and “&” it should allow us to obtain a certain range of entities. For example, let’s say we want 25 cars, we could do as follow:

GET /api/v1/cars?limit=25

We should also use some default values, so that if we have stored 1,000,000 cars are not all returned with a simple GET, if not the last 10 added ones are returned for example so that if the customer omits the attributes described for the ranges, by default a certain range is returned.

Use verbs when it is not a resource

Despite the insistence I have given on not using verbs, there are cases in which it is advisable to use verbs. For example, suppose we want to make a calculator embedded within an API, an example to ask you to add two numbers would be this:

GET /api/v1/add?a=1&b=2

It can also be useful to search for words in all models:

GET /api/v1/search?word=Foo

References