DEV Community

loading...
Cover image for How to develop/design an API that developers want to use

How to develop/design an API that developers want to use

rahulbanerjee99 profile image Rahul Banerjee Originally published at realpythonproject.com ・5 min read

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.

 

Good Names
- /cars
- /books/1

Bad Names
- /getCars
- /getBooks/1
Enter fullscreen mode Exit fullscreen mode

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

Good Names
- /cars
- /books

Bad Names
- /car
- /book
Enter fullscreen mode Exit fullscreen mode

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

A good endpoint would be
/libraries/2/books/10 
A not so good endpoint would be 
/books/10
Enter fullscreen mode Exit fullscreen mode

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://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

/cars?sort=+carName,-yearReleased
Enter fullscreen mode Exit fullscreen mode

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.

/cars?carName="XYZ"&yearRealeased="2020"
Enter fullscreen mode Exit fullscreen mode

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.

/cars?pageData=10&page=1
Enter fullscreen mode Exit fullscreen mode

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?


Connect with me on LinkedIn

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 Twitter, Medium, Dev.to, Hashnode, or my WordPress Blog

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/

Discussion (2)

pic
Editor guide
Collapse
lucianojung profile image
Luciano Jung

Hey there, great post. Two things I want to mention:

  1. I do not agree with the fact that the naming should be plural in any case. Although it's right if your response of all the data at this entry point is a list.
  2. I think you make a small mistake at the response code section. 203 has to be 403
Collapse
rahulbanerjee99 profile image
Rahul Banerjee Author

Hey! Thanks for the catch! Yup, it should be 403 and not 203. I think the name of the endpoint being singular/plural depends on the personal/team's preference as well. Personally, I prefer plural since it represents that there are multiple rows. Could you please elaborate on why you prefer singular?