Milan Latinović
Software Engineer and Enterprise Architect
What are the best Practices in REST API design
API design is an important aspect of modern software development. It allows different systems to communicate and share data with each other. A well-designed API can greatly enhance the user experience, while a poorly designed API can create confusion and frustration. In this article, we discuss some best practices in REST API design to ensure their effectiveness and ease of use.
It is also important to understand what REST is an architectural pattern. APIs which are aiming to follow this architectural patterns are commonly referred as “being RESTful”. However, not all REST APIs follow the best design principles and not all of them can be considered as RESTful.
This article guides you trough the best practices when designing REST APIs.
The best practices in REST API design
- Keep it simple
- Use consistent formatting
- Include comprehensive documentation
- Using proper HTTP status codes in Rest APIs
- Proper error handing as the best practices in rest api design
- Use descriptive and accurate error messages
- Use nouns instead of verbs in Rest APIs
- Using plural nouns for Rest API resources
- Use pagination in Rest APIs as the best practices in rest api design
- Versioning your Rest API
- Security concerns for the REST APIs
- Conclusion
Keep it simple
When considering the best practices in REST api design simplicity should be first thing in our mind. REST API should be easy to understand and use, even for developers who are new to the API. This can be achieved by using clear and concise naming conventions. Furthermore we can minimize the number of requests and parameters needed to complete a task.
For example:
# Good
/get_user_profile
/update_user_password
# Bad
/getProfileForUser
/changeUserAccountPassword
Use consistent formatting
The API should use a consistent formatting style, such as camelCase for variable names and HTTP status codes for responses. This makes the API easier to understand and use. This way developers will know what to expect when making requests and receiving responses.
API with inconsistent formatting does not follow the best practices in REST api design. For example:
# Good
{
"userId": 123,
"firstName": "John",
"lastName": "Doe"
}
# Bad
{
"USER_ID": 123,
"firstName
": "John",
"LAST_NAME": "Doe"
}
Include comprehensive documentation
The API should come with comprehensive documentation that includes examples of how to use the API, as well as explanations of the different endpoints, parameters, and responses. This will make it easier for developers to get started with the API and ensure that they are using it correctly.
In addition to comprehensive documentation, the best practices in REST api design suggest to provide a proper versioning for our REST API when applicable.
As the API evolves over time, it is important to provide versioning to ensure that developers using the API can continue to do so without breaking their code. This can be achieved by including a version number in the API’s base URL, or by using a custom header for versioning. For example:
# Version in base URL
https://api.example.com/v1/get_user_profile
https://api.example.com/v2/get_user_profile
# Custom header for versioning
GET /get_user_profile
API-Version: 1
GET /get_user_profile
API-Version: 2
Using proper HTTP status codes in Rest APIs
I was working on some projects where REST APIs always return status code 200, even if the API request failed. They provided error codes and description in the response, but the status code of the HTTP request was 200. This was wrong and clearly not the best practices in REST api design.
Using proper HTTP status codes is an important part of building a well-behaved REST API. The HTTP status code of a response should accurately reflect the status of the request, and it is important to use the correct status code for each type of response.
Here are some common status codes that you may use in a REST API:
- 200 OK: This status code indicates that the request was successful. The requested resource is being returned in the response.
- 201 Created: This status code indicates that a new resource has been successfully created as a result of the request.
- 204 No Content: This status code indicates that the request was successful, but there is no content to return in the response.
- 400 Bad Request: This status code indicates that the request was invalid and cannot be completed.
- 401 Unauthorized: This status code indicates that the request requires authentication and the user is not authorized to access the resource.
- 403 Forbidden: This status code indicates that the user is not allowed to access the requested resource.
- 404 Not Found: This status code indicates that the requested resource does not exist.
- 500 Internal Server Error: This status code indicates that an error occurred on the server while processing the request.
By using the appropriate status code for each type of response, you can provide a clear and consistent way for API users to understand the status of their requests.
Proper error handing as the best practices in rest api design
Proper error handling is important in any application, and it is especially important in REST APIs because these APIs often provide the interface between different systems and are critical to the functioning of those systems. When an error occurs in a REST API, it is important to handle the error in a way that is consistent, informative, and helpful to the API user.
Proper error handling is probably one of the most important best practices in rest api design.
There are several best practices for handling errors in REST APIs:
- Return appropriate HTTP status codes: The HTTP status code of the response should accurately reflect the nature of the error. For example, if a request is invalid due to a missing parameter, the API should return a 400 Bad Request status code.
- Provide a clear error message: The error message should be clear and concise, and should provide enough information for the API user to understand the problem and how to fix it.
- Use error codes: In addition to the error message, it can be helpful to include an error code in the response. This can be used by the API user to more easily identify and handle specific errors.
- Use appropriate logging: It is important to log errors in a way that is useful for debugging and troubleshooting. This may include logging the error message, error code, and other relevant information such as the request and response.
By following these best practices, you can ensure that your REST API provides helpful and informative error responses, which can make it easier for API users to use your API and for you to identify and fix any issues that may arise.
Use descriptive and accurate error messages
Accurate and descriptive error messages are essential for debugging and troubleshooting issues with the API. They should provide clear explanations of what went wrong and how to fix the problem.
Yes, this is very similar to the previous point to have proper error handling. Still it is important enough to have it within a separate section.
For example:
# Good
{
"error": "Invalid password format. Passwords must be at least 8 characters long and contain at least one uppercase letter, one lowercase letter, and one number."
}
# Bad
{
"error": "Invalid password"
}
Use nouns instead of verbs in Rest APIs
In REST APIs, it is best practice to use nouns instead of verbs to represent resources. This is because REST APIs are designed to be resource-oriented, meaning that they expose resources (represented by nouns) and allow the client to interact with those resources using HTTP methods such as GET, POST, PUT, and DELETE.
For example, consider an API for a library. Instead of creating an API endpoint with a verb such as “getBooks,” it is better to create an endpoint with a noun such as “books,” and use the HTTP GET method to retrieve a list of books. This follows the RESTful design principles and makes the API more intuitive and easier to understand.
Here is an example of how you might design the API endpoints for a library using nouns instead of verbs:
- GET /books: Retrieve a list of books
- GET /books/{id}: Retrieve a specific book by ID
- POST /books: Create a new book
- PUT /books/{id}: Update an existing book
- DELETE /books/{id}: Delete a book
By using nouns to represent resources and HTTP methods to indicate the desired action, you can create a clear and intuitive REST API that is easy to use and maintain.
Using plural nouns for Rest API resources
It is a common recommendation to use plural nouns when naming resources in a REST API. This is because a REST API is based on the concept of resources. In general, a resource represents a collection of similar items. For example, if you have a task-tracking application, you might have a “tasks” resource that represents a collection of all the tasks in the system.
Using a plural noun in this case helps to make it clear that the resource represents multiple items, rather than just a single item. For example, if you have a “tasks” resource and a “task” resource, it is clear that the “task” resource represents a single item within the “tasks” collection.
Overall, using plural nouns for resources in a REST API is a best practice because it helps to make the API more intuitive, consistent, and easier to understand.
Use pagination in Rest APIs as the best practices in rest api design
Pagination is a technique used to divide a large result set into smaller chunks, or pages, which can be returned to the client in separate requests. This is often necessary when working with REST APIs because it allows the API to return results more efficiently, and prevents the client from having to download and process a large amount of data all at once.
There are many ways to implement pagination in a REST API, but one common approach is to use query parameters to specify the page number and size. For example, consider the following request for a collection of tasks:
GET /tasks?page=2&size=10
In this example, the page
query parameter specifies the page number (in this case, page 2), and the size
query parameter specifies the number of items to include on each page (in this case, 10 items). The server would then return a response with the appropriate page of results, along with some metadata indicating the total number of pages and the total number of items in the result set.
To implement pagination in a REST API, you will need to do the following:
- Determine the number of items to include on each page, either by default or through a query parameter.
- Query the database for the appropriate subset of results based on the page number and size.
- Return the results to the client, along with metadata indicating the total number of pages and the total number of items in the result set.
- Allow the client to specify the page number and size through query parameters.
There are many libraries and frameworks available that can help you implement pagination in a REST API. Some popular options include:
- The
will_paginate
gem for Ruby on Rails - The
Paginator
class in the Django web framework - The
Pageable
interface in the Spring Data project for Java
Versioning your Rest API
There are several reasons why versioning a REST API is important:
- It allows you to make changes to your API without affecting existing clients. This is especially important if you have clients relying on a specific version of your API.
- It allows you to deprecate old versions of the API. This helps you to maintain a clean and streamlined API, and encourages clients to upgrade to the latest version.
- It allows you to roll out new features and improvements gradually, rather than all at once. This can be helpful for managing the risk of introducing breaking changes.
- It helps to ensure that your API is backwards compatible, which is important for maintaining the trust of your clients.
Overall, versioning your REST API is a good practice that helps to ensure the stability and maintainability of your API over time.
There are several ways you can version your REST APIs. Here are a few common approaches:
- URL Path: You can include the version number in the URL path of the API. For example:
https://api.example.com/v1/items
- Query Parameter: You can include the version number as a query parameter in the URL. For example:
https://api.example.com/items?version=1
- HTTP Header: You can include the version number in an HTTP header, such as
api-version
. - Media Type: You can include the version number as a media type in the
Content-Type
orAccept
headers.
It’s important to choose a versioning strategy that will be easy to maintain and understand for both the API developers and the API consumers.
Security concerns for the REST APIs
Here are a few best practices for security in REST APIs:
- Use secure communication channels: Use HTTPS instead of HTTP to encrypt the communication between the client and the server.
- Implement authentication and authorization: Use mechanisms such as OAuth, JSON Web Tokens (JWT), or API keys to authenticate users and authorize their access to API resources.
- Use input validation and sanitization: Validate and sanitize user input to prevent injection attacks (e.g. SQL injection, XML injection).
- Use output encoding: Encode API responses to prevent cross-site scripting (XSS) attacks.
- Use least privilege: Grant the minimum set of permissions required to perform a task, and avoid using shared credentials.
- Keep your API and dependencies up to date: Stay up to date with the latest security patches and updates to your API and its dependencies to prevent vulnerabilities.
- Monitor your API: Use logging and monitoring tools to keep track of API usage and detect security incidents.
By following these best practices, you can help to ensure that your REST API is secure and protect your users’ data.
Conclusion
This article presented you with the best practices in rest api design. By following these best practices, you can ensure that your API is easy to use, well-documented, and future-proof. This will make it more appealing to developers and increase its chances of success.
If you want to read more about this, there is an interesting stack overflow blog post with followup discussion on the best practices for REST API designs.