Behold, a scenario: I’ve got a site that sells t-shirts. It’s called Wit-T-Shirt, a clue to the hilarity of the slogans on the apparel.

Somewhere on this site there’s a button that lets a user add a product to their shopping cart. In the browser, clicking this button will call a function called addProductToCart and pass an object containing the product details and the ID of the user that did the clicking.

Then some other stuff will happen — the topic of this post.

Then eventually, on the server, a function addProductToCart will be called which expects the user ID and the details of the product. It will then go and check stock levels, update the user details in the database, calculate postage, and whatever else.

The way things start out and the way they end up are perfectly sensible, it’s the steps in the middle that have been troubling me.

The status quo

Up until now, I would have approached this the same way I think a lot of people do.

On the client (in that addProductToCart function) I’d split the data apart to create a URL with the user ID in it, then I’d initiate a network request with the method of POST (after spending 10 minutes Googling if it should be a PUT or a POST ) and stuff the remainder of the data in the body of that request.

On the server, I’d create a route to handle this request. It’s about the same in any language, but here it is in NodeJS with Express.

Have you heard, express.json() is back!

I’m taking the data that is now split between the URL, method and body, and joining them back together. The user ID from the URL, the product details from the body, and the fact that I want to add something to a cart is inferred from a combination of the HTTP method and the path.

Oh and for this request I’m not even using query parameters! If I were I’d probably want some code to turn a JavaScript object into a string that satisfies the requirements of that key/value syntax.

Speaking of URL encoding, what a strange little thing the URL is. I mean, think about it, the path is an array of variables — a mixture of resource descriptors and IDs — converted to a string and joined with / characters. Oh and also if there’s a ? in there, then the part after that is an array joined by & symbols, each of which is a key/value pair separated by an = symbol. And all in the form of a string with a limited set of allowed characters. What a terrible vehicle for transporting information!

If only there was a better way…

Introducing, the O API

An Obvious API is an API where you say what you want. It is a dumb name (especially the space after the O) but I’m sticking with it.

Let’s look at the above scenario implemented as an O API.

Since I no longer need to chop up my information and ram it in various holes of the HTTP specification, I can use the same URL and HTTP method for all requests — they no longer convey meaning.

In the body of the request I’ll say explicitly what I want to do ( action ) and pass the data needed to do it ( data ).

And on the server, I’ll replace my route with this:

Since I’m now sending all information in the body of a request, I can abstract all the other HTTP details into a function named something straightforward like sendToServer .

And now when I want to communicate with the server, I deal only in ‘actions’ and ‘data’.