Choosing how to design your REST API endpoints doesn’t restrict you to adhere to a concrete format, which is why there is a great level of freedom and flexibility in how you design them.
But, with this freedom comes responsibility. This responsibility is to make sure that we follow a certain architectural style when making choices about how we design our REST APIs.
This article explains the most important best practices and conventions to follow when designing your APIs, to support the client apps which use them, but also to make it understandable to developers who write those client apps.
URI stands for Uniform Resource Identifier and is a unique sequence of characters that identifies a logical or physical resource used by web technologies.
In our REST API endpoints, URIs identify resources and enable clients to access representations of that resource.
For example, if you wanted to expose a resource of articles to the client, you would add the following URI endpoint to your REST API:
The convention here is to use the plural form of nouns like
articles instead of
To understand why just suppose you want to give the client the ability to not only access “all articles” but also individual ones identified by their
In that case, you can add the following URI to your REST API:
If it’s not obvious at this point, just look at how logical this looks. We have a collection of articles, and we are accessing a specific article with a given
id in that collection.
It also potentially maps to the table in our database called
articles, where there are multiple rows in the table with each representing a single article identified by
Just take note that the
:id is presented with a semicolon here, which I used as a notation signifying that the API captures the value in that part of the URI and stores it into a variable with the name of
id. There are different ways of doing this in the actual code and that depends on the framework you are using to write your APIs.
The request actually contains an integer here e.g.
What I mean here, is don’t use something like
This is bad practice. Where the verb like
update, etc. is used to describe the operation being performed on the resource.
The operation performed on the resource is implicitly determined by the HTTP method the client uses to access a particular URI. The most common ones are of course
DELETE that correspond to
CRUD operations (Create / Read / Update / Delete).
Performing those operations in our example would look like:
/articles=> creating a new article in the collection of articles
/articles=> getting all current articles
/articles/:id=> updating a specific article with the given
/articles/:id=> deleting an existing article with the given
Another important convention to follow is to stay consistent with the relationship between objects by nesting parts of URIs so it reflects that relationship.
articles example, let’s say that our database contains a 1-to-many relationship between
comments on those articles. That means 1 article can have 1 or more comments.
To stay true to this relationship when designing our API endpoints, the URI should be consistent with it by nesting comments under an article. So in that case:
/articles/:article_id/comments=> URI used to access all comments on the article with a given article ID
/articles/:article_id/comments/:comment_id=> URI used to access a specific comment of a specific article
This also makes it easy for clients of your API to understand the relationship between objects of your app.
In the URLs of your REST APIs, use hyphens (
- ) instead of anything else, like underscores, to separate words, e.g.
For naming the GET query parameters, it’s acceptable to use underscores (
_) since those are considered variables.
Any error that occurs in the REST API server code when processing the request should never crash the process or app. Instead, always handle your errors, and instead of crashing, return a corresponding HTTP response code.
In that case, the response body can also contain a description of the error to be presented to the client/user.
Use GET query parameters to achieve filtering, pagination, or sorting of the results that are returned from your REST API.
GET query parameters are appended in the format:
to the end of the URL.
- Filtering: GET
/users?firstname=Jack—> returns all users which have “Jack” as their first name
- Pagination: GET
/users?page=5&results=10—> returns page number 5 where the complete users list is split into pages of 10 users
- Sorting: GET
/users?sort_by=firstname&order=asc—> returns all users sorted by their first name alphabetically A-Z
Of course, as you do changes during the life of the app or service you host, sometimes those changes are non-backward compatible.
In that case, you can support different versions of your API.
One example of how to do this is to include a version number at the beginning of your URIs, e.g.
/v2/articles/ /v2/users/ /v2/articles/:id
Old versions of the APIs should be kept intact to avoid breaking changes with clients that are using those old versions.
Although there are many more facets to consider, these are the most common best practices to use when designing REST APIs.
So, to summarize the best practices:
- Use the plural form of nouns in URIs
- Never use verbs in URIs
- Nest URI segments that match the hierarchy of relational resources
- Use hyphens to delimit words in the URIs
- Gracefully handle errors and return proper HTTP response codes
- Use GET query parameters for filtering, sorting, or pagination
- Always version your REST APIs to support backward compatibility