RESTful API Guidelines — Best Practices

An API is a computing interface that defines the requests that can be made to retrieve, change or update information in a web server through endpoints. In this guide, we will go through some important aspects when defining your API by following the REST architecture.

The post is organized in the following sections:

  • Introduction
  • HTTP Request Methods
  • Passing Information in the Request
  • HTTP Response Status Codes
  • Endpoints Naming Guidelines
  • Example Paths, Methods, and Requests
  • Throttling
  • Security
  • Popular Languages and Frameworks
  • Conclusion & Final Thoughts

Introduction

An API will allow you to provide your users or clients an interface where they can create, access, modify, or delete resources that you provide in a web server. The API is composed of endpoints, each of them is accessible by a path. The same path can be used by several endpoints by using different HTTP request methods.

Representational state transfer, or REST for short, is a software architectural style commonly used in web services. The main features of a RESTful system are that they are stateless and that they separate the concerns of the server from the client. The former means that both the server and the client do not need any information about each other’s state. The latter means that both the client and the server can be developed independently without affecting each other’s operation.

In this blog post, we will go through some of these methods, followed by how to pass information in a request, and the status code responses that you should use for each situation. After this, we will go through some guidelines on naming your endpoint’s paths, followed by a theoretical implementation example. Finally, we will go through some notions about throttling and security for your API and some possible programming languages in which you can implement it.

HTTP Request Methods

These are the types of requests that you will be using in your endpoints. Below we can see an example of the ones you can use in your API.

  • GET → Retrieve a resource or list of resources
  • POST → Create a resource
  • PUT → Update a resource
  • DELETE → Delete a resource

One important characteristic of these methods is their idempotence, which means their ability to be called several times without changing the result. From the four methods presented above, GET, PUT, and DELETE are idempotent whereas POST is not. So, for example, if you try to create several times the same resource, it might be created several times, depending on the implementation on the server. If you GET a resource several times, it will always return the same object.

There are other methods such as PATCH that can also be used, but unless you have a specific reason to require them, they might just add unnecessary complexity. Here is a full list of the HTTP methods with a description for each.

Passing Information in the Request

There are several ways in which we can allow the client to pass information in the request. Let’s learn the difference between them:

  • Path parameters → This is passed as part of the path when making a request. Normally used to select a specific resource via its ID.
  • Query parameters →This is what you would see at the end of the path represented by ‘?param1=xx&param2=yy’. Normally used to filter the resources.
  • Headers →These are part of the HTTP Request. They identify the type of content, encoding, among others. You can also add new fields, a common case is ‘x-api-key’ for authorization on a public API.
  • Body →This is used to pass information, normally encoded in JSON, although other formats such as XML can be used. This is where you will pass the information when creating a resource with POST or the fields you will update in a PUT or PATCH request.

When using a secure connection (HTTPS) all of these are going to be encrypted. Despite this, it is recommended that credentials in a login or register endpoint for example are passed in the body. This is due to the possibility of the path and query parameters being registered in the server logs or even in the clients browsing history.

HTTP Response Status Codes

These codes are used to inform the client with useful information about the status of their request, and in case of failure, the reason for that to have happened. The standard error codes are listed on the Mozilla Foundation website, along with a more detailed description.

2XX — Successful Responses

These are meant to inform the users that their request was correctly fulfilled. Some of the main codes in this group are:

  • 200 OK
  • 201 Created
  • 202 Accepted
  • 204 No Content

3XX — Redirect

Meant to inform the user that their request will redirect them to another page. For example:

  • 301 Moved Permanently
  • 304 Not Modified

4XX — Client Error

Whenever the request cannot be fulfilled because of some problem with the request. Some common examples:

  • 400 Bad Request
  • 401 Unauthorized
  • 403 Forbidden
  • 404 Not Found

5XX — Server Error

Whenever your server fails to produce the correct output for whatever reason, these codes should be in the response. Some examples:

  • 500 Internal Server Error
  • 502 Bad Gateway
  • 503 Service Unavailable

Endpoints Naming Guidelines

These are some general guidelines for the name of your endpoints. These will facilitate the organization in large APIs as well as allow the people using it to understand it more easily.

  • Use nouns
  • Use plurals
  • If possible, use a single word — If you need to use multiple words use a hyphen to separate them
  • Use the same route with different HTTP Request types for different actions

Examples:

On the left side is a wrong example, followed by the preferable form.

  • /employing → /employees
  • /house → /houses
  • /create-house →/houses (POST)
  • /update-house/:id →/houses/:id (PUT)

Example Paths, Methods, and Requests

Let’s imagine a scenario where we store in a DB a list of buildings. Each building is defined as the following object:

{
"city": string --> Name of the city where it is located
"height": int --> Height of the building in meters
"nStories": int --> Number of stories
"street": string --> Name of the street where it is located
"buildDate": int --> The year when it was built
}

In order to define the CRUD (Create, Read, Update, Delete) operations, we can use the following endpoints:

  • POST /buildings → Create a new building
  • GET /buildings → Retrieve the list of all the buildings
  • GET /buildings/:id →Retrieve a building by its id
  • PUT /buildings/:id → Update a building by its id
  • DELETE /buildings/:id → Delete a building by its id

Filters, Sorting, and Pagination

In the GET /buildings endpoint we can also provide filters, sorting and pagination support in order to allow to filter for an element, sort the list returned, or only return a limited number of elements, respectively.

  • filters — We can define a query parameter with the name city to allow the user to filter for buildings in a specific city.
  • pagination — We can also define a page and a limit parameter. The limit would be the number of elements retrieved whilst the page would allow the server to calculate how many elements to skip ahead.
  • sorting — We can use two query parameters: sortBy and sortOrder. The former will select which field we will be sorting by, whilst the latter defines if the order is either ascending or descending.

Note that these query parameters could have different names, the ones shown here are strictly used to demonstrate a possible implementation.

Examples

Considering a base URL where our API is served, say https://www.api.apiexample.com/v1, let’s provide a couple of examples:

  • GET https://www.api.apiexample.com/v1/buildings/1234?page=2&limit=10&city=london

Where 1234 is the id of the building (path parameter), and everything after the question mark are the query parameters, separated by the ampersand sign.

  • POST https://www.api.apiexample.com/v1/buildings/
body:
{
"city": london,
"height": 32,
"nStories": 9,
"street": "5th Avenue",
"buildDate": 1998
}

In this POST request, we create a new building with the corresponding fields passed in the body of the request.

Throttling

Throttling is a method used to limit the number of requests each user can make. This is useful to make sure that your server will not be overloaded by a single user or by a group of users. There are several ways of implementing throttling, some of the most common are:

  • Rate-Limit Throttling → Limits the number of requests that can be done in a specific interval of time by a certain user. This implies that you have to authenticate the users.
  • IP-level Throttling →You can limit the number of requests that can be made by each IP Address.

Security

Nowadays there is no reason to not force the TLS protocol so that every request has to be done over HTTPS. For this, you will need to get an SSL/TLS certificate that you can get from Let’s Encrypt for free, or from other providers like AWS Certificate Manager. The certificate will then have to be configured in your web server. We will not go into details as that would be a new topic to cover.

You might also want to use some sort of authentication/authorization to determine who is allowed to access your API. This will allow you to define several roles and apply the principle of the least privilege to define what access each role should have.

Popular Languages and Frameworks

Here are some examples of languages and one of the popular frameworks associated. Of course, there are several other popular languages for this type of application such as Java, Elixir, Ruby, among others. This is just to show you some of my favorites.

In terms of efficiency, Go should be the most performant of the three. In terms of packages and community, Node.js is probably the most complete. Finally, if the objective is to create a Minimum Viable Product (MVP) or if you are focused on simplicity, Python should be your choice.

Conclusion & Final Thoughts

In this guide, we went through several important topics when creating your RESTful API. We showed an example as well as some platforms that you can use to implement it. Most importantly, do not forget that these are guidelines to help you make decisions. You can deviate from them if you see fit.

Hopefully, this guide will help you get started or improving on your API. If you have any questions please feel free to leave a comment below!

If you are interested in learning more about how to create documentation to go with your RESTful API check out this guide that uses OpenAPI 3.0 and ReDoc.

See you in the next one!

Electrical and Computer Engineer working as a Software Engineer

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store