REST API Design Best Practices

Hey guys, in this article, we will discuss a few best practices for designing RESTful APIs. This post belongs to my favourite Java Best Practices Series category. Before designing and developing a REST API, I suggest you read this article to develop a good understanding of RESTful API principles.

What is REST?

REST stands for REpresentational State Transfer. Let's understand the meaning of each word in the REST acronym:

  • State: Refers to data.
  • REpresentational: Refers to formats (such as XML, JSON, YAML, HTML, etc.).
  • Transfer: This refers to carrying data between the consumer and provider using the HTTP protocol.

Learn more about REST at Java Guides.

Best Practices for Designing RESTful APIs

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 an Employee Management System:

  • Employee
  • Department
  • Projects
  • Task
  • Address

Example 2: Resources for a Student Management System:

  • Student
  • Teacher
  • School
  • Class
  • Subject

It is best practice to use nouns for resource identification.

For 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/100 - Updates a specific user
  • DELETE - /users/711 - Deletes a specific user

2. Use Plural Nouns to Name a Resource

When developing a resource in a REST API, use plural nouns. Consistency is key.

Examples:

  • 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 communication. The format must be specified in the HTTP header.

  • Content-Type: Defines the request format.
  • Accept: Defines a list of acceptable response formats.

Example:

  • Content-Type: application/json
  • Accept: application/json

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

To alter the state, use the PUTPOST, and DELETE methods instead of GET. Do not use GET for state changes.

Examples:

  • Incorrect: GET /users/711?activate
  • Correct: POST /users/711/activate

5. Use Sub-Resources for Relations

If a relation can only exist within another resource, model it as a sub-resource.

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 /cars/711/drivers/ - Returns a list of drivers for car 711
  • GET /cars/711/drivers/4 - Returns driver #4 for car 711

6. Use Proper HTTP Methods (Verbs)

Using the right HTTP methods ensures clarity and adheres to REST principles.

Examples:

  • GET: Retrieve data.

    • GET /api/books - Retrieve a list of books.
  • POST: Create a new resource.

    • POST /api/books - Add a new book.
  • PUT: Update an existing resource or create it if it doesn't exist.

    • PUT /api/books/123 - Update details of a specific book with ID 123.
  • PATCH: Apply partial modifications to a resource.

    • PATCH /api/books/123 - Update the title of a specific book with ID 123.
  • DELETE: Remove a specific resource.

    • DELETE /api/books/123 - Delete a book with ID 123.

7. HTTP Response Status Codes

When the client raises a request to the server through an API, the client should know the feedback. HTTP status codes provide standardized responses for various scenarios. The server should always return the right status code.

Common Status Codes:

  • 200 OK: The request is successful.
  • 201 Created: A new resource is created.
  • 400 Bad Request: The server failed to process the request due to malformed syntax.
  • 401 Unauthorized: Authentication is required.
  • 403 Forbidden: The server refuses to respond to the request.
  • 404 Not Found: The requested resource is not found.
  • 500 Internal Server Error: An unexpected error occurred on the server.

8. Field Name Casing Convention

Follow a consistent casing convention across the application. For JSON, use camelCase.

Example:

{
  "firstName": "Ramesh",
  "lastName": "Fadatare",
  "id": 100,
  "userName": "Ramesh Fadatare",
  "email": "ramesh@gmail.com"
}

9. Searching, Sorting, Filtering, and Pagination

Support these operations in the existing GET REST API by appending query parameters.

Examples:

  • Sorting: GET /companies?sort=rank_asc
  • Filtering: GET /companies?category=banking&location=india
  • Searching: GET /companies?search=Digital
  • Pagination: GET /companies?page=23

10. RESTful API Versioning

API versioning is the practice of managing changes to your API transparently. Common methods include:

  1. Versioning through URI Path
  2. Versioning through query parameters
  3. Versioning through custom headers
  4. Versioning through content negotiation

Example:

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

Read more about versioning REST APIs.

Real-World Use Case: E-commerce Platform API

Let's apply these best practices to design an API for an e-commerce platform that manages products, categories, and orders.

Resources

  1. Product

    • GET /api/products - Returns a list of products
    • GET /api/products/{id} - Returns a specific product
    • POST /api/products - Creates a new product
    • PUT /api/products/{id} - Updates a specific product
    • DELETE /api/products/{id} - Deletes a specific product
  2. Category

    • GET /api/categories - Returns a list of categories
    • GET /api/categories/{id} - Returns a specific category
    • POST /api/categories - Creates a new category
    • PUT /api/categories/{id} - Updates a specific category
    • DELETE /api/categories/{id} - Deletes a specific category
  3. Order

    • GET /api/orders - Returns a list of orders
    • GET /api/orders/{id} - Returns a specific order
    • POST /api/orders - Creates a new order
    • PUT /api/orders/{id} - Updates a specific order
    • DELETE /api/orders/{id} - Deletes a specific order

Use of Plural Nouns

All resources are named using plural nouns, ensuring consistency and clarity.

HTTP Headers for Serialization

The API supports JSON format for requests and responses.

Example:

  • Content-Type: application/json
  • Accept: application/json

Query Parameters for Searching, Sorting, Filtering, and Pagination

  1. Sorting Products:

    • GET /api/products?sort=price_asc - Sorts products by price in ascending order.
  2. Filtering Products:

    • GET /api/products?category=electronics&availability=true - Filters products that belong to the electronics category and are available.
  3. Searching Products:

    • GET /api/products?search=laptop - Searches for products with the keyword "laptop."
  4. Pagination:

    • GET /api/products?page=2&limit=20 - Retrieves the second page of products, with 20 products per page.

Versioning

The API uses URI Path versioning to manage different versions of the API.

Example:

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

Conclusion

In this article, we have discussed the best practices for designing RESTful APIs and applied them to a real-world use case of an e-commerce platform API. Following these guidelines will help you create APIs that are easy to use, maintain, and scale.

Learn more about REST at Java Guides.

Comments