APIs are like waiters - or are they?

By Mark Wharton

Application Programming Interfaces - APIs - are everywhere and take many forms and styles. Wikipedia defines them as

“...a way for two or more computer programs to communicate with each other”.

Your orrrder, sirrr

Which is fine if you know how computer programs work and the kind of things they need to communicate with each other.

How to explain an API to a non-technical person? “Oh, APIs are like waiters in restaurants…” you start off glibly, not knowing the deep water into which you’re about to wade.

It’s a commonly used analogy. I’ve used it myself many times:

An API is like a waiter…

You ask waiters for the dish you want and they bring it to you.  Programs ask APIs for the data or service they want and the API delivers it.

All analogies are simplifications. Let’s break this down. First let’s use the analogy to understand blocking and non-blocking APIs.

Blocking API: The fish and chip shop

This is the simplest and most common kind of API. You read the menu above the counter (the API documentation) and you ask the server for (call the function for) “Cod and chips - twice” (call the function cod_and_chips(qty=2) )

Cod and chips, twice, please

You, in this analogy, are the “client”; the person you talk to is quite literally the “server” (that’ll be important later). You wait until the server has wrapped up your cod and chips and they hand it to you. This is the Blocking part. You have to wait until the server has finished wrapping and you can’t do anything in the meantime.

Pre-cooked cod, yesterday

Blocking APIs are ok - provided what you want is do-able in the time you’re prepared to wait. Most fish-and-chip shops pre-cook chips and cod as they know this is a popular combo. (This is API caching, BTW). The waiting time is then quite short. What if, like me, you prefer haddock? Haddock is cooked on demand in my local chippy. Am I prepared to wait for the time that takes? Enter the…

 

Non-blocking API: Your ticket number is 53…

We’ve all seen this API. My chippy has used it since COVID as it allows you to phone them before arriving and so reduces the number of people hanging about in the shop. It’s also very prevalent in fast-food restaurants where you can now order from a screen rather than a person for the same public-health reasons. (I’m not convinced these screens aren’t a health hazard in their own right, but I digress…).

Now the relationship between client and server has changed. When I call the function, instead of returning me the thing I want, it replies, saying (by implication) “that will take a little while so, instead, here’s a unique number you can use to identify your order”.

This appears to be a great idea. Now I, as the client, am free to do whatever I want, armed, as I am, with the magic order number. What happens next is quite interesting. How do I know my order is ready?

If we want to keep this strictly client/server, the server (restaurant) has to implement some kind of protocol as I, the client, have no mechanism by which the server can initiate a conversation with me: it’s purely call and response, and I’m the caller.

The most stupid way of doing this is to offer an API end-point that returns “nothing” until such time as my order is completed. Only when it’s completed does it return my order. It goes something like this...

An annoying and unnecessary conversation

This sounds suspiciously like the kids in the back of the car on a family road trip “are we nearly there yet?” and, in computing terms, it’s nearly as annoying. The problem is that I, the client, am not actually “free to do whatever I want” while I’m waiting. Part of what I have to do is to ask repeatedly about the status of my order. This is called “polling” and it sucks. How often do I ask? Really frequently? In which case I’ll use up the server’s time telling me “no” when it could be making my order. Infrequently? In which case, I might get a negative response just before my order is ready and get cold fish and chips next time I ask.

The “call-me-back” API. Give us your mobile number. We’ll call you when it’s ready

The call-me-back API is a variation on the order number, except this one is two way. The unique “order” number in this version is replaced by my mobile number (given by me), rather than the order number (given by the server). It goes something like this...

Haddock and chips, twice, please

I hope you agree that this final version is preferable. It allows both the asker and the provider to get on with their lives and only communicate when there’s something to communicate (this is called “asynchronous” as the two halves are un-couple from each other). It’s “event driven”, and can be implemented using message queues. Imagine the above conversation being done over email or instant messenger - it would work just the same. Notice that I changed my language to “asker” and “provider” as there’s no longer a strict client/server relationship. The interaction is more symmetrical. The asker has provided an API for the provider to call (the mobile number).

Where’s my dinner?

What has all this got to do with my usual topics of conversation on this platform: digital twins and semantics? Allow me to explain…

Let’s start with finding an API. In our “waiter in a restaurant” analogy, that’s finding the restaurant you want in the first place. There are some API catalogues but they’re not very good, so you resort to Google and get millions of results. As a human you can work your way through them looking for the one you want. Once you’ve found the one you want, you can read the documentation (which is like the menu of the restaurant).

Documentation for APIs has improved over the years, thanks to OpenAPI, but still it’s aimed at humans, not computers. (Think of those literal translations of menus clickbait articles for how a computer might interpret the language). Once you’ve found the endpoint of the API you want (like the dish on the menu) you have to know how to call the API, with what parameters, whether it’s blocking or non-blocking, etc.

Semantics would solve all these problems. Semantics would allow you (or a computer) to find the API and to understand the endpoints and their parameters. This is the thrust of the FAIR data initiative, that data should be Findable, Accessible, Interoperable and Reusable. A truly FAIR API would be a wondrous thing to behold, but I’ve yet to see one.

At the other end of the spectrum there’s an individual Digital Twin. Depending on how we chose to model this, it might be the Restaurant, the Waiter, or the Dish itself. The most important thing is that it’s a single asset, not an API. It’s this restaurant; not a list of them. It’s Pieter, the waiter; not Peter. It’s cod and chips; not haddock. The individual asset has to be unique and discoverable.

What does “API” mean down at the digital twin level? To me, this is the most interesting bit of all… In a world where digital twins have behaviour and can therefore interact, they have to understand each other’s capabilities and data that they provide. That’s solved, as above, by semantics. They also have to choose one of the three operating modes of APIs discussed earlier.

In the next three examples, bear in mind the first principle of IOTICS. “The twin is in control of its own destiny”. That means, at one level, that any twin should be able to get on with what it wants to do with minimum disruption from other twins.

In blocking mode, twin1 would ask the other: “What’s the temperature of the chip fryer?” and then wait until twin2 responded. Twin1 would metaphorically be twiddling its twin thumbs while it waited, i.e. not in control of its own destiny.

Non-blocking mode is better, until twin1 has to poll twin2 for the answer. That polling is bad for two reasons: twin1 is spending its time doing the polling and not doing twin1 stuff and twin1 could, depending on how fast the polling rate was, deny service from twin2 by repeatedly asking for the answer.

The only mode that makes sense is the “call-me-back” mode. This minimises the coupling between the asker and the provider and, therefore, the time they spend doing nothing or wasting time on polling. It means that there’s no “client” and no “server”; the twins are peers in a symmetrical interaction. It’s asynchronous and very amenable to being implemented by message-based (event-driven) systems - also ideal in the Digital Twin world.

Now our conversation goes something like this:

Dramatis personae:

Twin of Mark (for it is he, well a twin of he, anyway)

Twin of Chippy

A very long winded way of ordering fish and chips. It's a good thing that computers don't get bored.

(There’s another version of this where the “your order is ready message” is replaced with someone on a bike delivering the fish and chips directly to your house. Delivery like this means I don’t have to go back to the chippy, but let’s leave that for part two of this blog)

We’ve come a long way from cod and chips to symmetrical, peer-to-peer networks of Digital Twins, each one of which presents a “nano service” of the capabilities and functionality of an individual asset. With the semantics in place, this should open the door to autonomous interoperability. I’ll raise my wooden fish fork in salute to that.

Anybody else hungry?

Previous
Previous

APIs are like waiters Part II