REST API Design Best Practices

Hey guys, in this article, we will discuss a few best practices for Restful API's design. This post belongs to my favorite Java Best Practices Series category. Before designing and developing Rest API, I suggest you read this article to develop a good Restful API.

What is REST?

The REST stands for REpresentational State Transfer.

Let's understand the meaning of each word in the REST acronym.

  •  State means data
  •  REpresentational means formats (such as XML, JSON, YAML, HTML, etc)
  •  Transfer means carrying data between consumer and provider using the HTTP protocol

Here are a few best practices to design a clean RESTful API.

1. Use Nouns for Resource Identification

The fundamental concept of a REST-based system is the resource. A resource is anything you want to expose to the outside world, through your application.

Example 1: Resources for Employee Management System:

- Employee

- Department

- Projects

- Task

- Address

Example 2: Resources for Student Management System:

- Student

- Teacher

- School

- Class

- Subject

A resource has an identifier, which is a URI that uniquely identifies that resource.

It is best practice to use nouns as resource identification.

For an easy understanding use this structure for every resource:
  • GET - /users - Returns a list of users
  • GET - users/100 - Returns a specific user
  • POST - /users - Create a new user
  • PUT - /users/ - Updates a specific user
  • DELETE - /users/711 - Deletes a specific user
Here is REST API design that I create before writing REST API. Refer to the URI that uniquely identifies the Employee resource:

Bad Practice: Do not use verbs like:

/getAllUsers
/getUserById
/createNewUser
/updateUser
/deleteUser

2. Use Plural Nouns to Name a Resource

When you have to develop the resource in REST API, just go with plural nouns. Don't mix up singular and plural, use plural nouns to name a resource.

For example:
Use /students instead of /student
Use /employees instead of /employee
Use /orders instead of /order
Use /users instead of /user
Use /customers instead of /customer

3. Use Proper HTTP Headers for Serialization Formats

Both client and server, need to know which format is used for the communication. The format has to be specified in the HTTP-Header.
Content-Type defines the request format.
Accept defines a list of acceptable response formats.
On the server-side, an incoming request may have an entity attached to it. To determine its type, the server uses the HTTP request header Content-Type. 

Some common examples of content types are “text/plain”, “application/xml”, “text/html”, “application/json”, “image/gif”, and “image/jpeg”.
Content-Type: application/json
Similarly, to determine what type of representation is desired on the client-side, an HTTP header ACCEPT is used. It will have one of the values mentioned for Content-Type above.
Accept: application/json

4. Get Method and Query Parameters Should Not Alter the State

Use PUT, POST, and DELETE methods instead of the GET method to alter the state. Do not use GET for state changes:
GET /users/711?activate or
GET /users/711/activate

5. Use Sub-Resources for Relations

If a relation can only exist within another resource, RESTful principles provide useful guidance.

In REST, the relationships are often modeled by a sub-resource. Use the following pattern for sub-resources.

GET  /{resource}/{resource-id}/{sub-resource}

GET  /{resource}/{resource-id}/{sub-resource}/{sub-resource-id}

POST /{resource}/{resource-id}/{sub-resource}

Example: 

GET  /{post}/{post-id}/{comments}
GET  /{post}/{post-id}/{comments}/{comment-id}
POST /{post}/{post-id}/{comments}

Use sub-resources child object cannot exist without its parent.

Few more examples for sub-resources:
GET /cars/711/drivers/ Returns a list of drivers for car 711
GET /cars/711/drivers/4 Returns driver #4 for car 711
These messages can be logically mapped to the /tickets endpoint as follows:
  • GET /tickets/12/messages - Retrieves a list of messages for ticket #12
  • GET /tickets/12/messages/5 - Retrieves message #5 for ticket #12
  • POST /tickets/12/messages - Creates a new message in ticket #12
  • PUT /tickets/12/messages/5 - Updates message #5 for ticket #12
  • PATCH /tickets/12/messages/5 - Partially updates message #5 for ticket #12
  • DELETE /tickets/12/messages/5 - Deletes message #5 for ticket #12

6. Use Proper HTTP Methods (Verbs)

HTTP methods used by most RESTful web APIs are:
The URL is a sentence, where resources are nouns and HTTP methods are verbs.
  • GET retrieves a representation of the resource at the specified URI. The body of the response message contains the details of the requested resource.
  • POST creates a new resource at the specified URI. The body of the request message provides the details of the new resource. Note that POST can also be used to trigger operations that don't actually create resources.
  • PUT either creates or replaces the resource at the specified URI. The body of the request message specifies the resource to be created or updated.
  • PATCH performs a partial update of a resource. The request body specifies the set of changes to apply to the resource.
  • DELETE removes the resource at the specified URI.

7. HTTP Response Status Codes

When the client raises a request to the server through an API, the client should know the feedback, whether it failed, passed or the request was wrong. HTTP status codes are a bunch of standardized codes which has various explanations in various scenarios. The server should always return the right status code.
Some of the frequently used status codes in this class are as follows:
  • 200 OK: This code indicates that the request is successful and the response content is returned to the client as appropriate.
  • 201 Created: This code indicates that the request is successful and a new resource is created.
  • 400 Bad Request: This code indicates that the server failed to process the request because of the malformed syntax in the request. The client can try again after correcting the request.
  • 401 Unauthorized: This code indicates that authentication is required for the resource. The client can try again with appropriate authentication.
  • 403 Forbidden: This code indicates that the server is refusing to respond to the request even if the request is valid. The reason will be listed in the body content if the request is not a HEAD method.
  • 404 Not Found: This code indicates that the requested resource is not found at the location specified in the request.
  • 500 Internal Server Error: This code indicates a generic error message, and it tells that an unexpected error occurred on the server and that the request cannot be fulfilled.

8. Field Name Casing Convention

You can follow any casing convention, but make sure it is consistent across the application. If the request body or response type is JSON then please follow camelCase to maintain consistency.
The below example uses camelCase as JSON field name:
	{
		"firstName": "Ramesh",
		"lastName": "Fadatare",
		"id": 100,
		"userName": "Ramesh Fadatare",
		"email": "ramesh@gmail.com"
	}

9. Searching, Sorting, Filtering, and Pagination

For searching, sorting, filtering, and pagination no need to create a new REST API, you can support these operations in the existing GET REST API, just append the query params with the GET REST API.
For example:
  • Sorting In case, the client wants to get the sorted list of companies, the GET /companiesendpoint should accept multiple sort params in the query. E.g GET /companies?sort=rank_asc would sort the companies by their rank in ascending order.
  • Filtering For filtering the dataset, we can pass various options through query params. E.g GET /companies?category=banking&location=india would filter the companies list data with the company category of Banking and where the location is India. 
  • Searching When searching for the company name in the companies list the API endpoint should be GET /companies?search=Digital .
  • Pagination When the dataset is too large, we divide the data set into smaller chunks, which helps in improving the performance and is easier to handle the response. Eg. GET /companies?page=23 means get the list of companies on the 23rd page.

10. Restful API Versioning

API versioning is the practice of transparently managing changes to your API.

Here are the 4 ways of versioning a REST API.

1. Versioning through URI Path

2. Versioning through query parameters

3. Versioning through custom headers

4. Versioning through content negotiation

Versioning through the URI Path strategy is widely used to version the REST API.

To version the REST APIs, just include the version number in the URI path.

Examples:

http://www.example.com/api/1/products

http://www.example.com/api/v1/products

http://www.example.com/api/v2/products

http://www.example.com/api/v1/posts

http://www.example.com/api/v1/employees

Read more about versioning REST APIs at https://www.javaguides.net/2021/04/rest-apis-versioning.html

Free Spring Boot Tutorial | Full In-depth Course | Learn Spring Boot in 10 Hours


Watch this course on YouTube at Spring Boot Tutorial | Fee 10 Hours Full Course

Comments