How to develop/design an API that developers want to use
Tags: programming, api, codenewbie, design
Published: 2021-04-06 16:04:43


If you are building an API, it is more than likely that it is going to be consumed by another developer. Your API must be easy to understand and easy to use. Below are few tips which can help you design an API that other developers will love

## Endpoint path must be a noun
The endpoint paths should ideally contain nouns and avoid verbs. The HTTP Verbs are sufficient in telling the consumer the purpose of the endpoint. 

```python
Good Names
- /cars
- /books/1

Bad Names
- /getCars
- /getBooks/1
```

If you use verbs, you will need to create a separate endpoint for all CRUD operations on an item. Making a PUT request to an endpoint named **/getCars** is really confusing.
On the other hand, if your endpoint path is a noun, you can just use the same endpoint with different HTTP verbs for the various CRUD operations. Making a PUT request to **/cars** makes sense so does a GET or a POST request to **/cars**

## Names of endpoints must be Plural
The names of the endpoints must be Plurals. This is important when trying to depict hierarchy in the URI. We will talk about hierarchy in the next paragraph. More often than not, data will be stored as collections and there will be multiple rows in the table. Therefore it is encouraged to use plurals when naming endpoints
```python
Good Names
- /cars
- /books

Bad Names
- /car
- /book
```

## URI must depict Hierarchy
The endpoint paths must be named in such a way that they tell the consumer about the hierarchy of the data they are trying to access. For example, if we have multiple libraries and each library has multiple books and we want to create an endpoint to give access to a specific book in a library
```python
A good endpoint would be
/libraries/2/books/10 
A not so good endpoint would be 
/books/10
```
In both cases, we are trying to access the book with ID 10. Although the second endpoint is not bad, the first endpoint gives the consumer information about the library ID and the hierarchy of the data.

## HTTP Verbs should only do their job

![https://medium.com/hashmapinc/rest-good-practices-for-api-design-881439796dc9](https://cdn.hashnode.com/res/hashnode/image/upload/v1617689027626/785-irNPh.png)

> 
https://medium.com/hashmapinc/rest-good-practices-for-api-design-881439796dc9

- A GET request is used to read multiple items or a single item. It should not alter the state of the database, i.e create a new item, delete an item or update an item
- A POST Request is only supposed to Create a single item or multiple items. It should have no other side effect
- A PUT request is used to update an item. It should not Delete or Create any items
- A Delete request should only be used to delete an item from a table.
- Ensure none of the requests have any side effects.

A request should only work on the data specified. I.e if the user is trying to add a book to a non-existent library, the post request to the book endpoint should not create a library record as well. Instead, the user should first be re-directed to the library endpoint. Following the successful creation of the library, they should be directed to the book endpoint.


## Support for sorting, filtering, and pagination
### Sorting
A feature should be implemented in the API which allows it to accept requests as follow
```python
/cars?sort=+carName,-yearReleased
```
Basically, the API is being asked to return all the cars sorted in ascending order by the field **carName** and descending by **yearReleased**

### Filtering
The user/developer should be given the ability to get filtered data based on the field specified.
```python
/cars?carName="XYZ"&yearRealeased="2020"
```
If a request like the one above is made, the API should only return the cars which were released in 2020 and have the name "XYZ"

### Pagination
Instead of returning all the data at once, the API should be able to send the data in batches or in the form of pages. 
```python
/cars?pageData=10&page=1
```
The above request tells the API that the user is requesting the first page with 10 records, i.e the first 10 cars. If the value for the parameter **page** is 2, the API should send the next 10 cars (car 11 - car 2). Therefore, if the user has a loop and keeps on incrementing the value for **page** during each iteration, they should get all the data in batches of 10

## Use the correct Response Code
As mentioned earlier, your API is most likely going to be used by other developers. There are different response codes for a reason, they help other developers debug errors in the request they made. Below are the standard Response Codes

- 200  -   Request was successful and some content was returned 💯
- 201  -    Request was successful and a resource was created. ✅
- 204  - Request was successful and no content was returned. Useful for DELETE requests ☑️
- 400 - Bad Request due to missing required parameters ❌
- 401 - Unauthorized. User is not authorized to access a request, most probably because they didn't log in 🚫
- 403 - Forbidden. The user has logged in and is authenticated but doesn't have the rights to view the resource. Maybe secured endpoint/data 🙅
- 404 - Not Found. The requested resource/endpoint could not be found ❓
- 405 - Method not allowed. Trying to make a POST request on an endpoint that only supports GET request or vice versa ✖️
- 500 - Generic Error. Thrown when none of the above codes are a suitable response code. Ideally should include a descriptive error message 😭

## Document your API
An API with good documentation makes it easier for other developers to use. Ideally, your API will have something like Swagger installed which will allow the user to make requests to the API without actually needing to write any code. 
Ensure all the endpoints are well-documented
Try to provide code snippets that access your API endpoints for all major languages
Include a sample request object and response object for each endpoint

## Conclusion
To summarize the above content
- Endpoint path must be a noun
- Names of endpoints must be Plural
- URI must depict Hierarchy
- HTTP Verbs should only do their job
- Support for sorting, filtering, and pagination
- Use the correct Response Code
- Document your API

If you have any other rules/tips for designing or developing API, do let me know in the comments. What are some good APIs you have worked with? What are some APIs you have worked with?

----
<!-- wp:quote -->
<blockquote class="wp-block-quote"><p>Connect with me on <a href="https://www.linkedin.com/in/rahulbanerjee2699/" rel="noreferrer noopener" target="_blank">LinkedIn</a></p></blockquote>
<!-- /wp:quote -->

<!-- wp:quote -->
<blockquote class="wp-block-quote"><p>I recently started a modified version of the #100daysofcode challenge. I aim to write content related to Python, Data Science, or Programming every day. Follow my progress on <a href="https://twitter.com/rahulbanerjee99" rel="noreferrer noopener" target="_blank">Twitter</a>, <a href="https://medium.com/daily-programming-tips" rel="noreferrer noopener" target="_blank">Medium</a>, <a href="https://dev.to/rahulbanerjee99" rel="noreferrer noopener" target="_blank">Dev.to</a>, <a href="https://realpythonproject.hashnode.dev/series/daily-programming-content/" rel="noreferrer noopener" target="_blank">Hashnode</a>, or <a href="https://www.realpythonproject.com/category/daily-programming-tips/" rel="noreferrer noopener" target="_blank">my WordPress Blog</a></p></blockquote>
<!-- /wp:quote -->

## Resources
https://stackoverflow.blog/2020/03/02/best-practices-for-rest-api-design/

https://www.vinaysahni.com/best-practices-for-a-pragmatic-restful-api

https://swagger.io/resources/articles/best-practices-in-api-design/