API Design Best Practices

Table of contents
Reading Time: 6 minutes

Ever wondered if we have anything like best practices for designing our APIs, if not just give it a quick thought something will pop up, and if it was a yes let’s talk about it in detail.

Yes, you heard me right, today we are going to talk about best practices for designing APIs which will help the developer to increase his/her productivity and success as an API is a user interface for developers. We will talk about all the design best practices one by one in detail.

API design best practices are as follows.

1. Always use Nouns, not verbs – Whenever you design an API always make sure you are using nouns not verbs, this is the very first principle of designing APIs and always keep the APIs simple and easy to understand.

There should always be two base URLs per resource. Let’s quickly design APIs for a resource User. Now the first URL will send a collection of users in response and the second URL will send a specific user from a collection in response.

For example –

First URL – /users  – sends a collection of users in response.
Second URL – /users/1 – sends a user with id 1 in response i.e. a specific user from a collection in response.

Never use verbs in your URLs

Some bad examples –

Make good use of HTTP methods to simplify APIs, take a look at the sample below

/users Create a new user Read all the users(Shows a list of all the users) Update all the users(Bulk update) Delete all the users
/users/1 Error Read a user with id 1 Update a user with id 1 Delete a user with id 1

2. Plural and concrete names – Singular noun or Plural noun, it has been seen both are used at times, but try not to mix them i.e. singular noun for some resources and plural noun for others, it is always better to go with plurals. Always have concrete names rather than abstract names as an abstraction is not always meaningful to developers.

3. Simplify associations and relationships – Handling association and relationship between resources. There will be scenarios wherein resources will have a relationship with another resource. What could be the best way to simplify this relationship in a web API?

Let’s say we are interested in users for a department, How would you model your API?

GET – /department/{id}/users  – this looks the best approach where we want to list down all the users for a particular department.

Similarly, we can have more HTTP verbs for different operations.

Now the relationship can be more complex where we introduce more resources, parameters, and state. So, the above approach will fail and become difficult for complex cases.

The solution is to use optional parameters or query param while designing your APIs

For example –  /users?department=1  – department here is optional and can be skipped
The developer will use this query param when he/she is interested in building a relationship between two resources.

This way, the developers will have more control over the APIs and he/she can consume it with ease.

Always introduce query param wherever required to simplify relationships and associations.

4. Handling errors – We sometimes ignore handling the exceptions as we always believe we will only have happy scenarios which might not be the case. Also, it is good to deal with errors upfront, so APIs should be designed in such a way that they deal with exceptions which might occur.

The API should always return sensible HTTP status code in case of error so that developers(consumers of API) could make out what went wrong and quickly fix things up. Typically errors are divided into two, one is client side errors for which we have 4XX series status code and second is server-side errors for which we have 5XX series errors.

A good example could be –
HTTP Status Code: 401
{“code” : 401, “message”: “Authentication Required”}

Best practices –  Use HTTP codes, Make messages returned in the payload as verbose as possible.

Start with these 3 first

  • Everything worked – success – 200 OK
  •  The application did something wrong – client error – 400 Bad Request
  • The API did something wrong – server error – 500 Internal Server ErrorAdd more gradually, like
  • 201 -Created
  • 304 – Not Modified
  • 401 – Unauthorized
  • 403 – Forbidden
  • 404 – Not Found

5. Versioning – Versioning is the most important part of designing APIs, you should always do versioning of your APIs. It is good to have two versions alive of your APIs at a time. Also, versions help identify the change in feature and other things.

For example – if you are currently ar version i.e. v2, keep the v1 also alive and when you switch to v3 just pull down the v1 version.

Example –  /v1/users

6. Pagination and partial response – Pagination allows you to give developers just the information they need. Let’s say I have an API which gives me a list of users and the list is very huge so there is no point sending the huge list in response as the developer will have to scroll through to find a subset of the list he/she is looking for, rather we can paginate the response where we will have a limited set of response from a huge collection.

Use these two parameters offset and limit  to paginate the response as these two parameters are widely used and common in the API world

Example – /users?offset=5&limit=10

& essentially allows us to use multiple parameters at a time. In the example above I am interested in viewing 10 elements from a huge collection and also I want to skip first 5 elements from a collection, this way developer can avoid a huge collection and can only view what he/she wants to.

You can also have default values for offset and limit, it is good to start with offset=0 and limit=25. These two parameters would be completely optional and can be skipped when not in use.

7. Snakecase(created_at) or Camelcase for field names – If JSON is the primary representation format then it is good to follow the Javascript naming convention which is camelCase, always remember to use camel case only because that is the naming once should follow.

8. Searching – For searching something the convention should be followed like ?q=.
Here we can follow the way Google search things on the internet, use ?q= in the API design.

For example – /users?q=physics+background

Searching helps in faster retrieval of the record on the basis of a key(s).

9. Filtering and Sorting – You can use filtering and sorting to limit the response based on some criteria.

Filtering – Filter users whose last name is ‘Singh’

Example – /user?filter={“op”=”eq”, params=[“Singh”],”key”=”lastname”}
The above example would filter the user collection on the basis lastname where lastname is equalto “Singh”.

Similarly, you can also apply sorting on the user collection, it can be in ascending or descending order.

Example – /users?sort=-lastname
The above example will sort the user collection in descending order.

Filtering and Sorting come handy when you want to limit the response or cut it down as per the requirement.

10. Caching – HTTP provides a built-in caching framework, where everything is managed by a response header.

There are two response headers one is E-TAG or LasModified, E-Tag is the response header which is commonly used, Etag header contains nothing but the hashed value of the response, whenever there will be subsequent requests from the client there will be a request header (If-None-Match) which is handled by browser itself and if the value of the request header and Etag matches there will be 304 Not-Modified from server which means nothing has been modified at the server end and it will save you from server trip and response will be served from cache as nothing has been changed at the server end.

Etag – Response header, generated by a server
If-None-Match – Request header, generated by a browser.

11. Authentication –  The latest authentication mechanism should be used to handle authentication, OAuth2.0 is the latest authentication mechanism, OAuth 2.0 will mean improved security and better end-user and consumer experiences with Web and mobile apps. As most of the APIs which require authentication will be using some sort of token passing to the user so that they could use the APIs seamlessly and smoothly.

Last but not least, let’s a take a look at all the HTTP status code. It’s really an important part of designing APIs.

2XX series status code
200 OK – Response to a successful GET, PUT, PATCH or DELETE.
201 Created – Response to a POST that results in a creation
204 No Content – Response to a successful request that won’t be returning a body (like a DELETE request)
209 Conflict – When the resource is already existing.

3XX series status code
304 – Not Modified – When the response is not changed at the server end.

4XX series status code
400 – Bad Request – Request is malformed.
401 – Unauthorized – Invalid authentication details provided.
403 – Forbidden – Authenticated user does not have access.
404 – Not Found – When a non-existent resource was requested
405 – Method Allowed – When an HTTP method is not allowed for a requested API.
415 –  Media Unsupported – If the incorrect content type was provided as part of the request
422 – UNprocessable Entity – Request failed against validations.
429 – Too Many requests – Request rejected due to rate limiting

5XX series status code
500 – Internal Server Error – Something went wrong with the server.

Bonus Tip – Always make sure your APIs have good documentation and some handy examples so that the consumer of the APIs could quickly start and experiment things at his/her end. Good documentation will always add value to it. The docs should show examples of complete request/response cycles.

This was the collection of API design best practices you can use while designing APIs.

Should you have any questions or queries, please write in comments. If you have enjoyed this post, I would be very grateful if you would help it spread. Keep smiling, Keep coding! Cheers!

Written by 

Deepak is a Software Consultant having experince of more than 5 years . He is very enthusiastic towards his work and is a good team player. He has sound knowledge of different technologies which include Java, C++, C, HTML, CSS, Javascript, C# always keen to learn new technologies.