Minimal Best Practices for Creating a well-designed API
Let’s say something about you first. If you came here from Google or from Medium itself, then — “ You are a man! You know, keep it up doing and one day you would be an Artist of your way!”
I assume that you are a mid level developer. So I don’t have to explain everything in details. But remember, the points I am going to say about designing API, contains a hell lot of information to share. I can make a series to explain it properly. To prevent making it large, I am just giving the head shots in this article.
So, Here are the main points we should keep on our head when we sit to write new APIs. They are all written in First Person because it will help me and you to take it as autosuggestion.
- I Use only nouns for my URI.
- My GET Methods should not alter the state of my resources.
- I Use plural nouns for my URI.
- I Use sub-resources for relationships between resources.
- I Use HTTP Headers to specify Input/Output format.
- I Provide users with filtering and paging for collections.
- I do Version my API.
- I Provide proper HTTP status code.
Let’s examine them.
1. Use only nouns for your URI :
It is appropriate to use NOUN instead of VERB in URI. HTTP has it’s own methods ( GET, POST, PUT, DELETE ) to clarify what should this API do. We should not rewrite them.
If we see
https://api.example.com/restaurants
is far better then
https://api.example.com/getAllRestaurants
The second example is violating the ReST principles. ReST API should express it’s resources, not methods.
If we look for some real APIs, we may realize the reality:
Twitter: https://api.twitter.com/1.1/statuses/user_timeline.json Atlassian: http://host:port/context/rest/upm/1/… Google Search: https://www.googleapis.com/customsearch/v1?parametersFacebook: http://graph.facebook.com/v1.0/me Delicious: https://api.del.icio.us/v1/posts/update
Last FM: http://ws.audioscrobbler.com/2.0/ LinkedIn: http://api.linkedin.com/v1/people/~/connections
Paypal: https://api.paypal.com/v1/payments/orders/<Order-Id>
Tumblr: api.tumblr.com/v2/user/
2. GET Methods should not alter the state of your resources :
We know HTTP provide us enough Methods. We should use them properly. If you done your POST thing using GET methods, change it bro.
GET is like a public variable. Your browser keeps cache them (most of the time). Even your search engine can crawl them if they are using rapidly. So if we want to secure our Database, we should not mix our GET with POST or PUT. Or even DELETE.
3. Use plural nouns for your URI :
We know ReST direct us to our resources. To guide our users, Plural Nouns Are Preferable, Rather Than Singular. It is a common conventions that are used in all good RESTful APIs.
For example, https://api.example.com/restaurants/
would response all the restaurant and https://api.example.com/restaurants/3
would return the restaurant no 3.
We should not hope to get all the restaurants in
https://api.example.com/restaurant
Does it make any sense to get all information of restaurant no 3 in this api?
https://api.example.com/restaurant/3
It can be a matter of discord that “If I want to response with just one restaurant, shouldn’t I use the singular one?”. The answer is, “You can. But it will make the other developers grief to jump from singular to plural here and there and beside you have to write things double!”
4. Use sub-resources for relationships between resources :
If we google it, we would see- “The main reason for this approach is readability; a nested resource URL can convey that one resource belongs to another one. It gives the appearance of a hierarchical relationship, like directories give in file-systems.”
It mainly show the connection between the resources in the URI.
These example URIs convey less meaning about the relationship:
/restaurants/:restaurantId
/ratings/:ratingId
Than these URLs:
/restaurants/:restaurantId
/restaurants/:restaurantsId/ratings/:ratingId
5. Use HTTP Headers to specify Input/Output format :
It is important to declare first what type of data set you are expecting or providing. Is it JSON, XML, or Plain Text? For both of your I/O operations.
This point tells about two things. Content-Type
and Accept
. Careful about what you want and what you deliver.
Recently I had faced an issue. I had to work with a well known company. I have to call their APIs and do further processing with the responses. What are they doing was, in one API they are responding me with JSON object, and in other API they are giving me just plain text! I spent a lot of time to catch that thing!
6. Provide users with filtering and paging for collections :
We know, killing users mobile data pack is not a good idea. If someone find out that you are consuming near 1 GB in just 1 or 2 hour ( except app like Youtube ), he would through your app out.
Except providing all data in a single call, we can chunk them and send them when ever they ask for more. It will save your server from unnecessary workload and your client from consuming unnecessary data packs.
Here is an example how we can do that :
https://api.example.com/resources?offset=0&limit=25
7. Do Versioning in API :
We do many updates. Sometimes it is small, sometimes it is big. Even in freelancing work we can not just through them after we have done. Sometimes those clients come again!
And those days, CI/CD puts updating app in daily routine! Even Coursera update itself many times in a day!
If our product is a web service like (SOA), what should we do to our updates? Should we integrate them all together? Or make a complete new service and shut down the previous one?
The best practice that was proven, is to versioning them. If we see the example of first point, everyone use the versioning in their APIs. Here is just two of them for you :
Paypal: https://api.paypal.com/v1/payments/orders/<Order-Id>
Tumblr: api.tumblr.com/v2/user/
And remember, don’t shutdown the previous one. If you have to, tell your customer first to update their version and then stop.
8. Provide proper HTTP status code :
This point is only about HTTP code. Not the error codes. Here is a thing that, our developers ( including me ) are mostly careful about the response body rather then the whole response.
As the character of HTTP, it provides the following thing and many others along with your expected response every time. You know when you get 200 status code. But do you know when would you get 204 status code?
Request URL:https://www.youtube.com/
Request Method:GET
Remote Address:172.217.160.142:443
Status Code: 200 OK
There are status code for ‘a resource has been successfully created’ and ‘a resource has been successfully deleted’. There are many of them. Using them correctly will helps the developers understand them clearly.
Thank you for finishing this up. There are several blogs about those practices. If you have time and interest please follow and share with us.