RestAPI Design Best Practices

Yashod Perera
4 min readApr 11, 2024

--

Design a proper RestAPI is crucial and most of the people end up with poorly designed APIs. In this tutorial we can learn how we can properly design a RestAPI. We will go through the following sections,

  1. Naming convention
  2. Versioning
  3. Query Parameters
  4. Idempotency
  5. Proper Status Codes Usage
  6. Error Handling
  7. Security
Photo by israel palacio on Unsplash

Naming

We need to make sure that we use nouns to represent resources. I have seen that most of the people end up with resources like following,

/getEmployees
/getBooks
/deleteStudent

Usually the action is represented by the HTTP method which can be either GET, PUT, POST, DELETE etc. The good naming convention should be as follows which must be plural.

/employees 
/books
/students

Okay, So how we know which action has been performed?

Different HTTP methods represents different actions.

  • GET — get resources
  • POST — create a new resource
  • PUT — update an existing resource
  • DELETE — delete an existing resource

Then following RestAPI provide the proper meaning to the reader as well.

GET /employees - get all employees
POST /employees - cretae an employee
PUT /employees/{id} - update a specific employee with id
DELETE /employees/{id} - delete a specific employee with given id
GET /customers/{id}/orders - get all the orders for customer with id

So we can represent the relationship when we design our RestAPI like /customers/{id}/orders .

Please use hyphens to improve the readability of your url.

Collections is group of resources which has the same name. As an example, GET /orders , POST /orders , DELETE /orders/{id} is a collection of order resource. When we design an API usually we design up to 2 to 3 levels.

Versioning

In RestAPI it is important to versioning your APIs, when we expose our API there can be many consumers for our API and it is not a good practice to change the responce or update the naming. If we are planing to do a change to the existing RestAPI collection then we should go with versioning.

Please understand that changing the API naming and payload depending on the requirement is a sign of a bad design but there are cases where we completely update our system and update our APIs to cater new requirements or relationships which needed the versioning

We can use v1 or v1.1 within the url to mention the version. /v1/orders/{id} is an example of how we can use versions.

Query Parameters

When we consider GET /orders that implies to get all the orders. But what if there are 10000s of orders? is it good to get everything and paginate? No.

When we design our APIs we need to consider the following.

  1. Pagination
  2. Filtering
  3. Sorting
  4. Fetch specific fields

All these details can be added to the API using query parameters.

GET /orders?page=1&limit=100 - we are getting first 100 orders
GET /orders?page=2&limit=100 - we are getting second 100 orders
GET /orders?page=1&limit=100&sort=date - we are getting first 100 order by date
GET /orders?fields=name,amount - only get name and amount

Important — when we design a GET resource it is important to have default limit in our end. As an example eventhough user has not mentioned any limit then the default should be defined number and there should be a maximum number that the user can go for.

If we can get the fields what we want why we need GraphQL? In RestAPI we are considering mostly the flat structure and fields query parameter is not good for a large set of fields and it cannot solve hierarchy structure projections.

Idempotency

Idempotency essentially means that the effect of a successfully performed request on a server resource is independent of the number of times it is executed.

As an example even we send multiple delete request for the same resource it should not change any states in the server other that deleting the mentioned resource. First delete to /orders/10 will return with 200 success and second orders/10 will return with 404 not found but the second call must not cause any additional changes in the server.

Please note that POST and PATCH are not idempotent.

Proper Status Code Usage

In RestAPI proper status codes matters similer to traffic lights. Status code provides the high level information of the response. Following are some examples.

  • 102 — Processing
  • 200 — OK
  • 201 — Created
  • 302 — Moved Permanently
  • 400 — Bad Request
  • 401 — Unauthorised
  • 403 — Forbidden
  • 404 — Not Found
  • 500 — Internal Server Error

There are lots of status codes and please note that depending on the first digit it provide some grouping.

  • 100–199 — Information processing
  • 200–299 — Successful response
  • 300–399 — Redirection messages
  • 400–499 — Client error messages
  • 500–599 — Server error messages

Error Handling

Error handling in RestAPI is crucial. We need to design the RestAPI to provide error information to make sure that,

  • Information to recover errors by the endpoint user — As an example if the amount is missing in the payload that should be mentioned.
  • Don’t expose too much of internal details — This is one of the most important where hacker can get these to attck the system. As an example direct database errors or any additional information must not pass to the end user
  • Using proper status code with the error

Security

Security needs a separate blog to cover and In this section I will pin point what to be done.

  • Using proper encryption — Need to use SSL/TLS to secure the data
  • Proper Authentication mechanisms
  • Proper Authorisation — Using ACLs (Access control list)
  • Rate Limits
  • Ip blacklisting
  • Block XSS attacks

Important — API manager can be used to handle the most of the security aspects and that component will make sure most of the security concerns.

If you have found this helpful please hit that 👏 and share it on social media :).

--

--

Yashod Perera

Technical Writer | Tech Enthusiast | Open source contributor