If you look at API today, it’s almost everywhere. It drives almost all kinds of applications. It is the visible backbone of the applications which helps to transfer data for processing, storing, manipulating, etc. You can say that in today's world API is everywhere. According to a survey, about 45% of global data transfer happens through API only. That’s a lot of data transfer share!
There’s a lot that goes behind the scenes or you can say behind the functioning of the API. The development of an API is a huge task where you’ll have to handle everything like designing, writing the code, optimization, documentation and the list goes on and on.
Let's take an example, you’re given an API that is poorly documented and has some weird API endpoints like the API is about a CMS and it gives you all the posts on endpoint
/getCategories and returns all the categories in
/getPosts. Do you think you’ll be able to make API connections without frustration? Not me!
So, there are some practices that we should follow while developing the API. These practices not only allow you to make a good API but also allows the API consumer to understand how to make API connections very easily.
Now we have covered a lot about the benefits of best practices and why it is important to follow the practices. Let’s move ahead with the main focus that is Best Practises of API development:
Well, the most important point in the list is Error Handling. This applies not for API development but also for other developers as well. When you’re working on an API, you have to handle the errors perfectly. Your API should throw a proper error in case the API fails or your code fails. The API should never return the plain error.
Let us think from the API consumer point of view, the consumer is trying to call your
/post but he is passing an invalid post ID in the parameters. Now in the backend, your API will try to find all the posts which are matching that ID but it doesn’t exist, right? So it’ll return null which should not be the case. You’ll have to return to the response body, what exactly happened in order to make the API consumer debug that issue.
I don’t think I need to tell you what are nouns and verbs right? Using nouns for API endpoint names not only sounds better there’s a reason behind this theory. We have got API methods where we’re already passing the verb so it might lead to making API endpoint naming useless.
Let us take an example of a CMS system, where you want to get the posts and publish the post. Now to make it easy for API consumers, you’ll try to make two endpoints that are
createPost. What if we can do both tasks in the same API endpoint? You can create an endpoint
/post where if you pass the method
GET, it should return all the posts while if you make the request in
POST method it should create a new article.
Basically, we have got API methods where we’re already using verbs like
DELETE. The API methods are already mapped to CRUD operations where
POST is used for submitting new data,
GET is used to read/fetch all the data,
PUT is used for updating the existing data, and as the name suggests
DELETE is used for deleting the data.
int data type JSON is the best option for transferring the data.
You can pass the
Content-Type header as
application/json to make sure the data being passed to and from API is in JSON and this will also ensure the client also interprets the same.
Every API responds with a code and each response code has some meaning in it. These response codes depict whether the API call was successful or not. Let’s take an example of a login system where users will be passing their credentials to log in. In case the user is logged in, it should not let the user access this endpoint. This is where response codes come into play where you define the responses in terms of codes.
Some of the response codes are:
They are also known as informational response codes. They are used when the request was received by the server and understood but to convey the client to wait for the response. Some of the examples are 100 - Continue, 102 - processing.
This response code indicates that the request was received by the API server, understood, and accepted by the server. They are used for successful API calls. Some of the examples are 200 - OK, 201 - Created, 202 - Accepted, etc.
These response codes are used for the redirection of URLs. When an API consumer hits an API endpoint, and if that URL is moved temporarily or permanently to some other URL then we use this endpoint. Some of the examples are 301 - Moved Permanently, 307 - Temporary Redirect, 308 - Permanent redirect, etc.
These response codes are used when the API consumer is trying invalid actions or you can say the issue is on the client-side not on the API server. Issued like incorrect method, incorrect credentials, etc. Some of the examples are 400 - Bad Request, 401 - Unauthorised, 403 - Forbidden, 404 - Not found, 405 - Method not allowed.
These response codes are used when there’s an issue on the API server-side and the server is aware of the issue. Some of the most popular examples are 500 - Internal Server Error, 502 - Bad Gateway, 504 - Gateway Timeout, etc.
Therefore, it is very important to pass the correct response code. You should never pass an error on success response codes and vice versa.
This is self-explanatory, your endpoint naming should be proper and try to avoid special characters in them. Let’s take the same example of the CMS system. You can create
/new-post but it’s better to use camel-casing here like
/newPost. Also, you should always name the endpoint accurately like
/post should not return the categories, instead, it should return what the name says that is posts.
This is one of the most important points here. Most of the developers who create API don't use them instead you can say that the API market is divided into two parts that is API consumers and API developers.
What if you create an API for an application and you have made it perfectly, everything is correct, working fine, it is using very cool tech, and whatnot. But when the API consumer starts to read the documentation they don’t know what’s going on.
API documentation is very important, not for API consumers but for you as well. When you’re working on a big API, you won’t be remembering all the endpoints. You also have to check your own API’s documentation. That is the reason why you should properly write the documentation and also provide a sample request in it.
There are a lot of API documentation tools, some of them are:
Every API evolves with time and requirements. As the application changes, new functionalities are added and new requirements come up so API evolves. When we should version the API? Well, you should not version your API when you’re making small changes like removing bugs, adding some very minor changes but when you’re making big changes like changing the response/request type, adding/removing endpoints, etc. They’re also known as breaking changes.
API versioning helps you to manage the complexity and lets you iterate faster when new changes are done. Versioned API lets you make changes whenever you want to without breaking the existing functionality of the API, this is one of the best parts of versioning. One important point to note here is that your new API should also support the past versions. Since you’ll be making changes in the API with time, it doesn’t mean that you should not focus on the older versions and just dump them in garbage directly. Because there can be a lot of API consumers who will still use the previous versions.
There are various methods by which you can version your API:
In this method, you just have to pass the version in the base URI. The method is very straightforward and easy to implement. For example, you can use
http://yourapi_url/v1 for the first version and once you push version 2 you can just simply use
http://yourapi_url/v2. Facebook uses this versioning method for its API.
In this method, you can just define a custom header that needs to be passed in every API call. This method allows you to preserve the existing URIs for future versions. For example, you can just define a custom header
API consumers can use the same API for different purposes, some consumers can use it to fetch all the data while some consumers need selective data. This is where pagination, filtering, and sorting comes.
Let us take an example, there’s an API endpoint
/post, now one consumer wants the only post with a specific
ID while another user wants the latest published post. Don’t you think it would be overkill to just dump all the data at once? Or the smarter way around is to return only what they want?
These techniques will not only allow you to save the server cost but also will help the API to respond in a much faster way with less resource consumption.
There are various methods to perform pagination, filtration, and sorting but the best method is to use the same endpoint with added query parameters.
To filter data you can just use,
/post/?id=21. You can just pick the
id parameter to return the post. Similarly, you can use
/post/?limit=10 for sorting and pagination respectively.
Suppose you’re working on a High Volume, High-Speed API. Where your API needs to return the data and store the data very fast like 1000 requests per minute. You already know there are some endpoints that are used more than others. You also know that it has to return the same data again and again for a particular amount of time. Don’t you think hitting the database again and again will increase the cost as well as time? What if, you have already stored that data in the cache and whenever the consumer hits that endpoint you can just use cached data instead of hitting the database again and again?
The caching can be done on several layers of the API and there are a lot of methods that you can use to cache the data. Some of them are:
SSL Verification will allow your API to receive requests from secured sources only. This is important to prevent attacks on your API which will eventually affect all the other API consumers as well. Suppose, ‘/post’ is bombarded with some malicious code from an unknown source. It’ll start consuming all the resources and other verified users who are trying to access the API will face difficulty.
Before launching any API, you should always test it first whether it is returning the correct data or not, it is working fine or not. This will ensure that your API consumers will not face any bugs and issues while calling the API.
There are a lot of API testing tools available in the market and you can use any of them to test your API. Some of them are:
We have listed some of the best practices for API development. This will help you to make your API stronger and easy to manage. These practices are widely accepted by the developers and help them to maintain the discipline of their API. Being an API developer, you’ll face a lot of challenges but they’ll make you a better developer. You might be following some other practices, you can just comment them down in case we have missed any.