Best Practices for rest APIs

Jolly Fish
Technically True🚀
4 min readSep 7, 2020
Photo by Simone Hutsch on Unsplash

This article is composed of a summary of the Stack Overflow blog article “Best practices for REST API design” by John Au-Yeung

Accept and Respond with JSON

JSON is the standard for transferring data. The reason is that most networking technologies have tools to process it: JavaScript has built-in methods to encode and decode JSON either through the Fetch API or another HTTP client. Server-side technologies have libraries that can decode JSON without doing much work.

XML isn’t widely supported as it requires prior conversion to a form which may be used by network frameworks, i.e. JSON. Further, client side manipulation is hard

To inform the client that an app responds with JSON data, set Content-Type in the response HTTP header to application/json. Certain frameworks rely on this header to parse received data

Use nouns instead of verbs in endpoint paths

We should use the nouns which represent the entity that the endpoint that we’re retrieving or manipulating as the path-name. This is because our HTTP request method already has the verb

GET retrieves resources. POST submits new data to the server. PUT updates existing data. DELETE removes data. The verbs map to the CRUD operations

With the two principles we discussed above in mind, we should create routes like GET /articles/ for getting news articles. Likewise, POST /articles/ is for adding a new article , PUT /articles/:id is for updating the article with the given id. DELETE /articles/:id is for deleting an existing article with the given ID.

Name collections with plural nouns

To deal with collections instead of a single entity, the noun representing the collection of entities/resources should be in the plural form. Tables usually have more than one entry and are named to reflect that, so to be consistent with them, we should use the same language as the table the API accesses.

With the /articles endpoint, we have the plural form for all endpoints, so we don’t have to change it to be plural

Nesting resources for hierarchical objects

The path of the endpoints that deal with nested resources should be done by appending the nested resource as the name of the path that comes after the parent resource.

For instance, if we want an endpoint to get the comments for a news article, we should append the /comments path to the end of the /articles path. This is assuming that we have comments as a child of an article in our database. Thus the resulting endpoint would look like: '/articles/:articleId/comments'

Handle errors gracefully and return standard error codes

We should be throwing errors that correspond to the problem that our app has encountered

HTTP Error Code Graph

Allow filtering, sorting, and pagination

Sometimes, there’s so much data that it shouldn’t be returned all at once because it’s way too slow or will bring down our systems. Therefore, we need ways to filter items

We also need ways to paginate data so that we only return a few results at a time. We don’t want to tie up resources for too long by trying to get all the requested data at once

Filtering and pagination both increase performance by reducing the usage of server resources.

For filtering, the fields to be filtered are passed via the URL’s parameters as follows /employees?lastName=Smith&age=30
For sorting by certain fields, pass the fields to be sorted are passed as URL parameters under a “sort” field name as follows: /articles?sort=+author,-datepublished

Where + means ascending and - means descending. So we sort by author’s name in alphabetical order and datepublished from most recent to least recent.

Maintain Good Security Practices

Using SSL/TLS for security is a must. To enforce the principle of least privilege, we need to add role checks either for a single role, or have more granular roles for each user.

Cache data to improve performance

We can add caching to return data from the local memory cache instead of querying the database to get the data every time we want to retrieve some data that users request.

There are many kinds of caching solutions like Redis, in-memory caching, and more. We can change the way data is cached as our needs change.

Versioning our APIs

We should have different versions of API if we’re making any changes to them that may break clients. The versioning can be done according to semantic version (for example, 2.0.6 to indicate major version 2 and the sixth patch) like most apps do nowadays.

Versioning is usually done with /v1/, /v2/, etc. added at the start of the API path.

--

--