With the advent of .Net Core, web Api have become more common. Apologies to my non-dotnet background friends, but with .net hands-on, its always inclined towards .net. Coming straight to the point, be it Mobile Apps, SPAs (Single Page Applications), micro-services or name whatever, you will see REST everywhere. In background of this post, old kishore kumar songs are running, so don’t offend a bit of nostalgia 😊.
But as in most cases, everyone is so busy in implementing the APIs, many of my friends don’t ever pay attention on how an API be named. Or rather, not an API but the endpoints and methods (hate to call them methods). Well, for an API the problem there is no standard as such, but rather some best practices, that should be followed ‘ideally’. Lets discuss them one by one. Most importantly, in this post shall be talking only on the API naming. I also had OpenApi in mind, but lets leave it for another post. So lets dive in.
Its all Noun
To understand an API, first we need to understand definition of Noun. Well, by simple definition Noun is a name place or thing. APIs are all nouns or rather its the way the should considered by. The background lies in the fact that a single refers to a resource or collection of resource. Also, many people will argue that we are doing some operation. They are not wrong arguably, as many have been core developers and form the naming convention for methods, standard practice is to put the verb there.
But APIs are a special child. When speaking of REST API naming, the action is represented not by name of the api, but rather the HTTP Verb. So its like a verb on a Noun makes the complete working thing. Additionally REST operates on URI or the Uniform Resource Identifier which is an unique address of a resource. It will be bit more clear with next few paras.
With Noun, comes the VERBS
Before we begin further, HTTP Verbs. HTTP verbs are the basic operations that are supported by the WEB specs. Basically it could be anything as long as the client can speak and sever can listen the same word. But majorly following are the most common HTTP Verbs
While options doesn’t do anything in terms of api operations and is used mainly for preflight which tells you what url are supported by api along with Cors, it needs a separate discussion. Lets jump further.
Get me the list.
Assuming, we are writing an API for casino games. Lets discuss some basic operations around it, lets begin by basic naming.
GET /api/v1/games //Returns the all
As apparent, this returns the list of all games. “/api/v1” is my base path. games is my Rest endpoint that provides all games. Note that it should not be “
/api/v1/getallgames” or “ /api/v1/getmygames“. The reason is simple. get action is defined using the HTTP verb. So reading the complete API it would read as “Get Games” implicitly all.
Provide me the object now.
Lets discuss a bit more complex case with a second level URI. Assuming i have an API that provides available games for a country. In this case first task would be to identify a country before jumping on an API. Again, assuming I am looking into India, so my route would look like
Note the the countries is a similar route as games above only thing is we are passing the country code after it which becomes URI for India. So now, we have identified a country, lets fetch games for India.
GET /api/v1/countries/in/games //Gets all games in india.
Cool. Now if this api returns a list of games as an json, next step to open a game is to get its URI which would look something like
GET /api/v1/countries/in/games/poker23 //poker23 is id of the game
Create a new Game.
With this we are now able to access a game with id of poker23. So thats more less done on the fetching side. What if we wanted to create a game. The verb for that is POST, and endpoint would be the base games uri. So post would look like
POST /api/v1/games //POST or Create to games collection
Creation is once, update is always.
In the body payload data would be provided and in return I should get a 201 with the location href in response headers. Cool. Let’s quickly jump to update part. Update is a bit more complex because there are 2 contenders over here as we call it PUT and PATCH. The cases are pretty much simple. Whenever complete object is needed to be updated, PUT is used, and whenever a single field is needed to be updated, Patch is used. But, interestingly, the change in the address would be that now the address would be URI for the game, not for the collection. So the endpoint would seem like
POST /api/v1/games/poker23 //poker23 is id, body is complete payload. PATCH /api/v1/games/poker23 //pass in the field to be updated
Interesting point to note over here is that PUT should always be idempotent. by that it means, the body should be self contained and should provide everything that is needed to recreate the object, ID being from the URI.
John must Die. The DELETE
The Delete operation is also very similar, just apply the delete verb on the URI.
DELETE /api/v1/games/poker23 //poker23 is id,
it has to be small
One last thing to cover, is casing of the url. Ideally best practice is that the uri(s) should always be in small. For many of windows developers, it actually doesn’t matter, but feel the pain of linux developers and when the app moves to containers. And although the there are quite good handling around same, we should always play safe and uniform.
API naming is very simple. Keep in mind “Verb” acts on a “noun” and you are done. In this series, next posts shall be coming shortly on other REST core concepts like HATEOAS, query params, GraphQL and other intresting stuff. Keep Watching.
good concept explained. i am a software developer for about 7 years working in REST and can say this is really nice and very well explained.
One question, if a resource needs to be updated or created, what should be the verb to be used, POST or PUT.
Well, it depends. There are some industry standard best practices, but every developer uses his own set of standards. In general, best practice states that we should use PUT for such cases. As per definition, in case the resource does not exist, it creates the resource, in case it does, it updates it. This is because as mentioned above, PUT payload should be idempotent for a given URI. This means that the payload should be self capable of (re)creating the resource at the given URI in case it does not exist.
However, companies and developers tend to use their own defined practices. I have used both POST and PUT in such cases. The key is to remain consistent for the given API set.
Drop a message in case of any other queries 🙂