REST in Peace

Mauro Ghiani
5 min readNov 8, 2019

--

The “ Mahāparinibbāṇa” Sutra records at first the Buddha passing and entering into Nirvana. It’s a canon, then. But also a manifesto for the general public since it is indeed an excellent blueprint of sacred literature. It’s a typical maybe recorded speech of the Enlighten One, that starts with: “Thus have I heard. “ at least mentioning that we can hear but not listen, we can listen and do not understand, or simply miss it in the whole. Starting a religion out of a chit chat, a simple gossip is something really notable; it seems that Buddhism does not uphold sacred words but points to something else, whatever it is.

Thomas Laird, Majestic Illumination. Taschen, 2018

So when Representational state transfer (REST) was born, Roy Fielding imagined something like HTML plain data in web pages, a representation of a resource denoted unequivocally by a Uri linked to some other related resources (HATEOAS). Also, he defined some semantics about HTTP methods (get, post, put, delete… etc), and some constrain about RESTful systems that are the reasons today so many systems smell like it. Notably, when we talk wanders about REST we forget that one of the characteristics of it is being stateless. Now, what are relational DB, no-SQL, sessions, cache, Jwt tokens, and cookies all about? It seems that the very bases of Roy Fielding’s wishful thinking are denied every second throughout the internet.

Let’s say it, play and simple, like in the Buddha’s story, that the value of REST lays somewhere else and it is not just some paper written in the 2000s. Recently I came up with a modern layered interpretation of the original that signed three important points for REST:

Level 1: Resource address base Uri
Level 2: Http methods and status
Level 3: Use Hypermedia

Does it sound like something new? Or is it REST already in everything we have dealt with, for instance when writing an API? And with this goes some problems:

  1. A single resource does not provide any meaning of pre-fetching, it’s in the very idea that a single endpoint should represent a single resource. So you can’t join resources or bits and views of data since it is ḥalāl.
  2. If you create or update a resource, and I will use the verb “save”, you can’t exactly go with a single POST(for creating something new) or a single PUT (for updating).
  3. If you need only an entity, let’s say a product why we should add some hypermedia info like categories when my scope in the API is not enforcing discovery by the developer but simply domain, readability, and documentation?

Interestingly in the new ASP.NET Core 3.0 Web API docs presenting some examples the RESTful philosophy pours in:

Tutorial: Create a Web API with ASP.NET Core

Now, when REST becomes an obsession and only words are remembered everything falls apart. Let’s start with an example (each resource is identified by a Uniform Resource Identifier (URI) used throughout HTTP for identifying resources), we want to view an image on a web server, for instance, IIS:

GET https://mydomain.com/someimage.png

but there’s no image, hence the web server responds with a 404.

404 - File or directory not found.
The resource you are looking for might have been removed, had its name changed, or is temporarily unavailable.

What does that mean?

The target of an HTTP request is called a “resource”, whose nature isn’t defined further; it can be a photo, a video, or anything else. The 404 error status code indicates that the REST API can’t map the client’s URI to a resource but may be available in the future. Subsequent requests by the client are permissible.

It means we don’t know whether the image is really missing or we made a mistake with the URI. The same applies if we have a handler or an API ControllerBase, we might have been calling the wrong method or the wrong endpoint. In fact, no indication is given by the webserver whether the condition is temporary or permanent. So what happens when we ask for an item by the ID that does not exist?

GET /api/TodoItems/{id}

A Restful application should throw a 404

return NotFound(new NotFoundError("The item was not found"));

but also we might get a 404 if we wrong the URI:

GET /api/TodoItems2/{id}

So how to make an API consistent using REST but giving more insight to the developer who wishes to consume it?

First of all, we could keep HTTP messaging and error code but only outside the domain of the application, for instance, if we’re calling an inexistent endpoint. Then we could pack the HTTP error code straight in the response and give, if the endpoint e the methods are right, always a 200. We could use a class like this one:

public class Result<T, M>
{
public bool Success;
public T Data;
public IList<M> Errors;
}

where errors bring in the HTTP error code semantics:

public class NotFoundError : HttpError
{
public NotFoundError()
: base(404, HttpStatusCode.NotFound.ToString())
{
}
public NotFoundError(string message)
: base(404, HttpStatusCode.NotFound.ToString(), message)
{
}
}

So if we have a product or some data we ask for, that is not existent, we could respond a 200 in a JSON fashion way:

{
"success": false,
"data": null,
"errors": [
{
"statusCode": 404,
"statusDescription": "NotFound",
"message": "The product was not found."
}
]
}

This is plain REST, only the HTTP messaging is delegated to a higher level but semantically holds on. If I’m not wrong this is like the ISO/OSI layer where protocols are enveloped one in the other. Let’s say HTTP in TCP/IP, where TCP and Ip are the Transport and Network protocols and HTTP is the Application protocol.

So in the end, Rest cannot be a religion, strictly speaking, and we don’t need to go by the book but adapt and survive. And like the Buddha reach Nibbana.

--

--

Mauro Ghiani
Mauro Ghiani

Written by Mauro Ghiani

A complete non sequitur being.

No responses yet