A Quick Web API REST Refresher
So, I have been creating and working with web api’s since the early 2000’s. First with perl cgi-bin requests, PHP simple RPC style POST/GET requests, than SOAP with PHP and .NET, than .NET http handlers with xml, binary, csv, etc…..and over the last decade web apis with .NET MVC, WebApi’s, NodeJs with JSON, and I have seen all arrays and different approaches to implementation.
Ever since we came into the Web Api era around 2009, there was a big shift to using the REST
pattern and terminology with json
, sure we have things like Graphql
now, though for the most part REST
is a fairly simple pattern to use. However it’s often misunderstood even by experienced developers.
REST
is really just designed to work the way the stateless HTTP
protocol was designed for. Contrary to popular belief, It doesn’t force certain approaches, rather just uses http the way it was intended. Using verbs, resources, http status codes and the like.
Though some popular patterns have emerged via REST
that make it simple and consistent to apply, irrespective of platform used. Let’s look at some now.
Rest deals with resources, now a resource could represent an entity record in a database, it could represent a process, a job, task, a collection of items. typically a resource refers to a single element. Though a resource, could have sub-resources and the like.
Let’s look at HTTP
verbs in the REST context:
-
POST
used for creating resources. -
GET
used to query resources, get a collection, get a single item (with an id), with filters and so on. -
PUT
for updating a specific resource -
DELETE
to delete/remove a specific resource -
PATCH
for making amendments, changes to specific parts of a resource
Now lets look at the most popular HTTP Status Codes
:
Anything in 2xx
range is a Success status
-
200 OK
- everything’s a-ok, request and process is success -
201 Created
- ok, we have created a new resource that’s ready, and a link to that resources metadata/status will be in the responseslocation
header. -
202 Accepted
- ok, we acknowledge the request though may not have fulfilled it yet, it could be a long running process, however we have a link in thelocation
header to obtain completion status, and possibleretry
headers. A client app can potentially poll thislocation
to see when it’s completed or reached another status ( note: this is http semantics, not talking about event messaging and the like at this point ) -
204 No Content
- ok success, though we have no content to return..
Now 4xx
codes represent an issue with the client request
-
400 Bad Request
- something in the clients request is malformed, invalid, or simply incorrect, often used for field validation. This means a client should not retry a request without changing something in it. -
401 Unauthorized
- the client has not sent up adequate authorization, be it anAuthorization
header, or a cookie, or it’s expired, etc. Usually an indication for a client to login.
And 5xx
indicate a server error of some sort. They may be transient errors, and a retry could potentially work.
-
500 Internal server error
- unhandled or unknown server errors, exceptions and the like. (dont use 400’s for these). -
502 Bad Gateway
- could be a range of issues, from the web server, to proxies, dns etc.
Ok got it, so now look at how they typically work.
-
POST
is used to create a new resource with data in body, the server returns http201 Created
for a resource that is created and ready, or202 Accepted
to indicate acknoledgement of the request, though resource may be long running. In both instances the url to retrieve the resources metadata/status via aGET
is supplied in thelocation
header. -
GET
is used to query a collection of resource items, or a single item with an id… it typically returns a200 OK
. Now when usingGET
with an explicitid
to fetch a single item, this will often (not always) represent the same url route as what thePOST
returns in thelocation
header. -
PUT
is used to update an explicit resource. It could return a200 OK
or204 No Content
. -
PATCH
is not used as often, however it is similar to aPUT
except where a put is about updating a resource,PATCH
is designed for updating specific parts of a resource, lets say explicit fields, perhaps a status etc. -
DELETE
is to delete/remove/cancel an explicit resource. It could return the deleted resource with a200 OK
or just confirmation with a204 No Content
.
Notice the key point is when using
POST
, the webapi should provide thelocation
header with the url to the resource created/acknoledged
Ahhh so what about REST routes
Now routing is where things get interesting… often devs will call their API’s REST
based because they use verbs and response codes, however their routing conventions may be more aligned with RPC
(Remote Procedure Call) approaches.
As mentioned before REST
does not enforce particular conventions, however recommends certain concepts. Let’s look at a typical REST convention example.
Let’s say we have a resource called products, in rest we typically use the pluralized form “products” to represent a collection of product in a similar way to how database tables are often named (NOTE: remember REST uses resources, does not neccassarily have to tie back to database records.). This way we can apply consistent routing conventions regardless of the resource for most CRUD like operations.
NOTE: before you consider that CRUD won’t suit your particular services, and therefore REST wont work. CRUD here is just used as an example for a base set of operations, as it’s familiar for database operations.
Example REST-like routing style:
POST /api/products
GET /api/products
GET /api/products/?optionalFilter1=filterValue&limit=10
GET /api/products/{id}
PUT /api/products/{id}
PATCH /api/products/{id}
DELETE /api/products/{id}
With this approach in this example there are effectively 2 routes that use different HTTP VERBS to determine the actual operation on the resource. One route defines the resource collection, the other defines an explicit item within that resource collection
/api/products - resource collection
/api/products/{id} - explicit item within resource collection
REST style API routes define resources, and HTTP Verbs define operations. REST came about as a way to provide consistency and standardization for a web based http environment.
Now contrast this with an RPC
style api routing
POST /api/addproduct
GET /api/getproductslist
GET /api/getproduct/{id}
POST /api/updateproduct
DELETE /api/deleteproduct
Now with the RPC
routing, we have 5 routes, indicating the operation, and using potentially any verb, ie POST
is often used instead of PUT
, and even sometimes DELETE
…. the core point being that the route itself defines the operation…. its akin to calling a function, or procedure by name as in Remote Procedure Call
.
Now RPC
is essentially the style many traditional developers have used to call API’s for decades as it translates to older traditional API’s.
RPC style API routes define operations, HTTP Verbs are typically POST/GET, though can be any combination.
Sometimes there is a mix of REST/RPC styles in routing.
Recommendation:
Aim for consistent, and standardized web practices, in essence REST
is very helpful in this regard, especially as API’s grow in scale and functionality. The larger the API the more you need consistency.
References:
- For more details on Http status codes, look at the Mozilla HTTP status page.
- http://apihandyman.io/do-you-really-know-why-you-prefer-rest-over-rpc/
- https://restcookbook.com/
- https://cloud.google.com/blog/products/application-development/rest-vs-rpc-what-problems-are-you-trying-to-solve-with-your-apis
- https://blog.jscrambler.com/rpc-style-vs-rest-web-apis/
REST Api Examples:
- https://docs.github.com/en/rest
- https://developer.okta.com/docs/reference/core-okta-api/
Comments