12 REST API Best Practices to follow in 2023

By Josip Miskovic
A thumbnail showing a programmer developing a REST API.

As a developer, you understand the importance of having an API that is reliable, secure and easy to use. By following REST API best practices, you can make sure your API meets these standards.

I've been developing APIs for over 10 years and here's my list of most important REST API best practices:

1. Follow the URI Naming Conventions

URIs in REST APIs should follow specific naming conventions for consistency and clarity.

Convention Description Example
Use Lowercase letters URIs should start with a letter and use only lowercase letters.

/users, /orders

Use Plural nouns

Plural nouns should be used in the URI to identify collections of resources.

/users, /orders

Hyphen separate resource names

Literals/expressions in URI paths should be separated using a hyphen ( - ) for readability.

/user-info, /order-history

Underscore separate query strings

Literals/expressions in query strings should be separated using underscore ( _ ).

/users?sort_by=name, /orders?filter_by_status=completed

Use sub-resource collections for relations

Sub-resource collections should exist directly beneath an individual resource to convey a relationship to another collection of resources.

/users/{user_id}/orders, /orders/{order_id}/items

Use top-level resources (when possible)

We should aim for limited nesting of resources.

/items/{item_id}

2. Use HTTP methods to communicate intent

One of the key principles of REST APIs is the use of standard HTTP methods to communicate the intent of the request.

HTTP Method Description
GET Retrieve a resource
POST Create a new resource
PUT Update an existing resource
PATCH Partially update a resource
DELETE Delete a resource

Read more: PATCH VS PUT


Do not use verbs in the URI.

Here's an example of what to do and not to do:

Incorrect Correct
GET /getAllUsers GET /users
POST /createUser POST /users
PUT /updateUser/1 PUT /users/1
DELETE /deleteUser/1 DELETE /users/1

3. Use appropriate data structure

It's a common misconception that REST API must use JSON structure. But REST is all about a resource. That resource can be a JPEG image, HTML document, or any data structure.

Find out what works for you. A lot of company API guidelines force the use of JSON.

Valid JSON schema

If you use JSON, follow these best practices:

  1. Valid JSON Schema should be used for both request and response bodies.
  2. Include the "Content-Type" header set to "application/json" in all requests and responses when sending JSON data.
  3. Use JSON even when communicating error messages. Don't just return plain text or HTML.

JSON (JavaScript Object Notation) is a lightweight data-interchange format introduced in December 1999 as part of ECMA-262 3rd Edition Standard. It was designed to be easy for humans to read and write.

4. Pick your JSON field naming convention (and stick to it)

JSON standard doesn't impose a field naming convention, but it's a best practice to pick one and stick with it.

Convention Description Example
snake_case Lowercase letters with underscores separating words "user_name"
camelCase

Lowercase first letter of first word, capitalizing the first letter of subsequent words

"userName"
PascalCase Capitalizing the first letter of each word "UserName"
kebab-case Lowercase letters with hyphens separating words "user-name"

camelCase and snake_case are the most common. I prefer camelCase and I don't recommend PascalCase or kebab-case.

5. Communicate with HTTP status codes

Status codes are a standard part of the HTTP protocol, and they allow you to quickly convey information about the outcome of a request.

By using HTTP status codes in your API responses, you help your clients build their error handling.

Monitoring tools such as Application Insights and App Dynamics use HTTP status codes to understand the current state and health of an API. For example, if you use a status code in the 200 range even when the operation fails, the monitoring tool won't know that something went wrong.

Here is a table that lists the most important HTTP status codes:

HTTP Status Code Description
200 OK

The request was successful and the response body contains the requested data.

201 Created The request was successful and a new resource was created.
204 No Content

The request was successful but there is no representation to return (i.e. the response is empty).

400 Bad Request

The request was invalid or cannot be served. The request should not be repeated without modification.

401 Unauthorized

The request requires authentication and the user has not provided valid credentials.

403 Forbidden

The server understands the request, but it refuses to authorize it.

404 Not Found

The requested resource could not be found but may be available in the future.

500 Internal Server Error An internal server error occurred while processing the request.

Read more: HTTP Bad Request vs Not Found

6. Do not maintain state

A REST API should not maintain state on the server. That's the responsibility of the client.

This is important because it allows for the API to be cacheable, scalable, and decoupled from the client.

For example, an ecommerce API might use cookies to maintain the state of a shopping cart. However, such approach violates key the key principle of RESTful APIs - they need to be stateless.

7. Version your APIs

API Versioning is important because it allows for backward compatibility, enables the introduction of new features without breaking existing clients, and allows for phased rollouts of changes.

Here are the most popular ways to version a REST API:

Versioning Method Description Format
URL path

The version number is included in the URL path, such as "api/v1/resources"

api/v1/resources
URL query parameter

The version number is included as a parameter in the URL, such as "api?version=1"

api?version=1
Custom request header

A custom header, such as "X-API-Version" is used to specify the version number

X-API-Version: 1
Content negotiation

The client specifies the desired version through the use of the "Accept" header in the request

Accept: application/vnd.company.resource-v1+json

The URL path versioning method is the most popular because it is easy to see which version of the API you're using by just looking at the URL.

Keep in mind that different clients can use different versions of your API, so it increases maintenance.

When should I introduce a new version of an API endpoint?

A new version of an API endpoint should be introduced when there is a change that is not backward compatible with previous versions.

This could include changes to the request or response format, changes to the resource being accessed, or changes to the expected behavior of the endpoint. Additionally, a new version may be introduced if a major overhaul or redesign of the endpoint is needed.

It's important to version the API so that existing clients can continue to work with previous versions while new clients can take advantage of the new functionality.

8. Document your API thoroughly

Thoroughly documenting an API involves several key steps:

  1. Create concise API documentation: Include all of the endpoints with their request and response bodies.
  2. Provide code examples: Include examples in multiple programming languages to demonstrate how the API can be used.
  3. Use clear and descriptive error messages: Clearly communicate what errors may occur and how to handle them.
  4. Offer interactive documentation: Use tools like Swagger UI or Postman to provide an interactive documentation experience for developers.
  5. Document security: Explain how the API can be secured and what kind of authentication is required.
  6. Explain rate limiting: Clearly communicate any rate limits and how they are enforced.
  7. Offer detailed release notes: Keep developers informed of any changes or updates to the API.
  8. Provide support resources: Offer resources such as a developer forum or support center to help developers with any questions they may have.
  9. Regularly update documentation: Regularly update the documentation to ensure it remains accurate and relevant.

Consider providing interactive documentation, such as Swagger or Postman, to help developers understand how to use your API.

9. Use consistent error messages

In most cases, HTTP status codes are not enough to explain what went wrong.

To help your API consumers, include a structured JSON error message.

The response should include the following information:

  1. Error code: A machine-readable error code that identifies the specific error condition.
  2. Error message: A human-readable message that provides a detailed explanation of the error.
  3. Error context: Additional information related to the error, such as the request ID, the request parameters that caused the error, or the field(s) in the request that caused the error.
  4. Error links: URLs to resources or documentation that provide additional information about the error and how it can be resolved.
  5. Timestamp: The time when the error occurred.

Figure out what works for you and stick to it. Every error message in your API should follow the same format.

For example:

json
HTTP/1.1 400 Bad Request
Content-Type: application/json

{
    "errorCode": "INVALID_INPUT",
    "message": "The input provided is invalid.",
    "details": [
        {
            "field": "firstName",
            "issue": "required field is missing"
        },
        {
            "field": "lastName",
            "issue": "required field is missing"
        }
    ],
    "request_id": "5124129901",
    "timestamp": "2022-12-10T13:46:20.857Z"
}

The HATEOAS best practice for REST APIs states that the API should not define fixed resource names or hierarchies, as this creates a coupling between the client and server.

Instead, the server should provide instructions to the client on how to construct appropriate URIs through media types and link relations, allowing the server to control its own namespace. This ensures that the resource structure is not determined by out-of-band information and the interaction is driven by hypertext.

Roy Fielding, the designer of the REST principles, states that REST APIs must be hypertext-driven.

Example:

json
{
  "articles": [
    {
      "id": 1,
      "title": "How to Build a RESTful API",
      "author": "John Doe",
      "date": "2022-01-01",
      "links": [
        {
          "rel": "self",
          "href": "https://api.example.com/articles/1"
        },
        {
          "rel": "author",
          "href": "https://api.example.com/authors/1"
        }
      ]
    },
    {
      "id": 2,
      "title": "Building Scalable APIs",
      "author": "Jane Doe",
      "date": "2022-02-01",
      "links": [
        {
          "rel": "self",
          "href": "https://api.example.com/articles/2"
        },
        {
          "rel": "author",
          "href": "https://api.example.com/authors/5121"
        }
      ]
    }
  ]
}

11. Consider applying a rate limit for API calls

Rate limiting is a technique for limiting the number of API requests that a client can make in a given time period.

The API response will usually include information about the rate limit and the client's current usage, so that the client can adjust its behavior accordingly.

A "429 Too Many Requests" HTTP status code and the "Retry-After" header are commonly used to enforce rate limits on API calls.

  • The 429 Too Many Requests error status code indicates that the user has sent too many requests in a given amount of time and the API has temporarily blocked further requests from that user.
  • The Retry-After header specifies the amount of time the user must wait before making additional requests.
  • The Retry-Remaining header specifies the count of remaining calls in the given time frame.

The HTTP working group has proposed a draft for RateLimit-Limit, RateLimit-Remaining, and RateLimit-Reset header fields to communicate request quotas in HTTP. These headers allow servers to communicate current request quotas and clients to shape their request policy to avoid being throttled.

12. Use query parameters

Query parameters allow you to provide additional information in the URL of an HTTP request to control the response returned by the server.

Use query parameters to:

Action Description Example
Filter Return only the relevant results for a specific request /users?name={name}
Sort Order the results in a specific manner /users?sort_by=age
Paginate Divide the results into manageable parts or pages

/users?page={page_number}&per_page={results_per_page}

What's your API maturity level?

The Richardson Maturity Model is scale that measures the maturity of a RESTful API design.

It goes from Level 0 (worst) to Level 4 (best).

Here's more about the levels:

  • Level 0: The Swamp of POX (Plain Old XML) - This level represents a basic use of HTTP as a transport protocol to exchange XML payloads. There is no notion of REST or its constraints.
  • Level 1: Resources - API is designed around resources, with each resource being identified by a URI.
  • Level 2: HTTP Verbs - This level emphasizes the use of HTTP methods to perform operations on resources, in line with the REST constraint of using a uniform interface. The API may also start to incorporate hypermedia links to represent relationships between resources.
  • Level 3: Hypermedia Controls - At this level, the API uses hypermedia controls to drive the application state and allow the client to interact with the API in a more decoupled manner. The client is no longer dependent on prior knowledge of the API structure, but instead uses hypermedia links to navigate the API.
  • Level 4: The Hypermedia-Driven Web - This is the highest level of maturity and represents an API that fully embraces the REST constraint of hypermedia as the engine of application state. The client interacts with the API entirely through hypermedia controls, making the API more flexible and resilient to change.

These levels are very useful tool for evaluating how well you've applied the best practices.

Does your API need to be Level 4 to be considered REST?

No, the Level 4 is very difficult to achieve.

After all, "principles" and "best practices" are not set in stone.

Use your best judgment.

There are so many real world scenarios, do what's best for your project.

Josip Miskovic
About Josip

Josip Miskovic is a software developer at Americaneagle.com. Josip has 10+ years in experience in developing web applications, mobile apps, and games.

Read more posts →
Published on:
Download Free Software Developer Career Guide

I've used these principles to increase my earnings by 63% in two years. So can you.

Dive into my 7 actionable steps to elevate your career.