Chapter 7: Real-time API communication
By Bryan Cooksey • Published January 23, 2024
In Chapter 6, we learned about designing APIs by building our own. At this point, we have a lot of hard-earned knowledge, and it's time for it to start paying off. We are ready to see how we can put APIs to work for us. In this chapter, we learn four ways to achieve real-time communication through APIs.
What is a real-time API?
Real-time APIs are APIs that enable near-instantaneous communication between systems, allowing users to get virtually immediate responses to their actions. Where REST API, as we discussed in the last chapter, uses the response-based HTTP protocol, real-time API keeps open communication between clients and servers. Since this course is meant to be a primer on APIs in general, we won't get too nitty-gritty with the details of how this type of API works right now.
Obviously, real-time communication can be a huge advantage, as it can continually update users with the latest data without requiring them to request it. It also makes APIs more scalable for growing enterprises while making systems more efficient and improving data accuracy and timeliness.
Real-time API examples
Real-time APIs have a huge range of use cases—many of which you probably benefit from without even realizing it. As technology integrates even further into our daily lives, they're likely to grow even more ubiquitous.
Here are just a few common real-time API examples.
- Internet of Things (IoT) devices: That Bluetooth thermostat in your home? Real-time APIs allow you to monitor the temperature and change it with the tap of a finger.
- Push notifications: Every time you get a Google Calendar notification on your phone that you're about to start a meeting you forgot about, you're using real-time APIs.
- Live chat: Your favorite chat apps rely on real-time APIs to send communications from one user to another the instant they hit the send button.
- Geolocation: In order to track your location as you drive, GPS apps need real-time APIs.
- Live data feeds: Those Wall Street brokers you see in the movies need real-time APIs to watch stock prices rise and dip on that revolving digital stock ticker.
- AI applications: APIs facilitate real-time communication between applications and AI models, allowing these applications to analyze human-written text, process it, and deliver responses based on data from existing datasets.
Real-time API integrations
Let's remind ourselves why APIs are useful. Back in Chapter 1, we said that APIs make it easy to share data between two systems (websites, desktops, smartphones). Straightforward sharing allows us to link systems together to form an integration. People like integrations because they make life easier. With an integration, you can do something in one system and the other will automatically update.
For our purposes, we will split integrations into two broad categories. The first we call "client-driven," where a person interacts with the client and wants the server's data to update. The other we call "server-driven," where a person does something on the server and needs the client to be aware of the change.
Client-driven and server-driven are our terms, so don't be surprised if you use one in front of a developer and get only a blank stare in return. Mention polling or webhooks if you want instant credibility.
The reason for dividing integrations in this manner comes down to one simple fact: the client is the only one who can initiate communication. Remember, the client makes requests and the server just responds. A consequence of this limitation is that changes are easy to send from the client to the server, but hard to send in the reverse direction.
To demonstrate why client-driven integrations are easy, let's turn to our trusty pizza parlor and its API for ordering pizzas. Say we release a smartphone app that uses the API. In this scenario, the pizza parlor API is the server and the smartphone app is the client. A customer uses the app to choose a pizza and then hits a button to place the order. As soon as the button is pressed, the app knows it needs to make a request to the pizza parlor API.
More generally speaking, when a person interacts with the client, the client knows exactly when data changes, so it can call the API immediately to let the server know. There's no delay (since it's real time) and the process is efficient because only one request is made for each action a person takes.
Once the pizza order is placed, the customer might want to know when the pizza is ready. How do we use the API to provide them with updates? Well, that is a bit harder. The customer has nothing to do with making the pizza. They are waiting on the pizza parlor to prepare the pizza and update the order status. In other words, the data is changing on the server and the client needs to know about it. Yet, if the server can't make requests, we appear to be stuck.
Solving this type of problem is where we utilize the second category of integrations. There are a number of solutions software developers use to get around the client-only requests limitation. Let's take a look at each.
When the client is the only one who can make requests, the simplest solution to keep it up-to-date with the server is for the client to simply ask the server for updates. This can be accomplished by repeatedly requesting the same resource, a technique known as polling.
With our pizza parlor, polling for the status of an order might look like the following.
In this approach, the more frequently the client makes requests (polls), the closer the client gets to real-time communication. If the client polls every hour, at worst, there could be a one-hour delay between a change happening on the server and the client becoming aware of it. Poll every minute, instead, and the client and server effectively stay in sync.
Of course, there is one big flaw with this solution. It is terribly inefficient. Most of the requests the client makes are wasted because nothing has changed. Worse, to get updates sooner, the polling interval has to be shortened, causing the client to make more requests and become even more inefficient. This solution does not scale well.
If requests were free, then nobody would care about efficiency and everyone could just use polling. Unfortunately, handling requests comes at a cost. For an API to handle more requests, it needs to utilize more servers, which costs more money. Scale this cumbersome situation up to Google- or Facebook-sized proportions, and you're paying a lot for inefficiency. Hence, lots of effort has been put into optimizing the way the client can receive updates from the server.
One optimization, which builds off of polling, is called long polling. Long polling uses the same idea of the client repeatedly asking the server for updates, but with a twist: the server does not respond immediately. Instead, the server waits until something changes, then responds with the update.
Let's revisit the polling example from above, but this time with a server that uses the long polling trick.
This technique is pretty clever. It obeys the rule of the client making the initial request while leveraging the fact that there is no rule against the server being slow to respond. As long as both the client and the server agree that the server will hold on to the client's request, and the client is able to keep its connection to the server open, it will work.
As resourceful as long polling is, it too has some drawbacks. We'll skip the technical details, but there are concerns like how many requests the server can hold onto at a time or how to recover if the client or server loses its connection. For now, we'll say that for some scenarios, neither form of polling is sufficient.
With polling ruled out, some innovative software developers thought, "if all our trouble is because the client is the only one making requests, why not remove that rule?" So they did. The result was webhooks, a technique where the client both makes requests and listens for them, allowing the server to easily push updates to it.
If this sounds like cheating because now we have the server making requests to the client, don't worry. What makes webhooks work is that the client becomes a server too. From a technical perspective, it's sometimes very easy to extend the client's functionality to also listen for requests, enabling two-way communication.
Let's look at the basics of webhooks. In its simplest form, webhooks requires the client to provide a callback URL where it can receive events, and the server to have a place for a person to enter that callback URL. Then, whenever something changes on the server, the server can send a request to the client's Callback URL to let the client know about the update.
For our pizza parlor, the flow might look a little something like the following.
This solution is excellent. Changes happening on the server are sent instantly to the client, so you have true real-time communication. Also, webhooks are efficient since there's only one request per update.
Building on the idea of webhooks, there have been a variety of solutions that aim to make the setup process dynamic and not require a person to manually enter a callback URL on the server. You might hear names like HTTP Subscriptions Specification, Restful Webhooks, REST Hooks, and PubSubHubbub. What all of these solutions try to do is define a subscription process, where the client can tell the server what events it is interested in and what callback URL to send updates to.
Each solution has a slightly different take on the problem, but the general flow looks like the following.
Subscription-based webhooks hold a lot of promise. They are efficient, real-time, and easy for people to use. Similar to REST's explosive adoption, a tide is rising behind the movement, and it's becoming more common for APIs to support some form of webhooks.
Still, there will likely be a place for polling and long polling for the foreseeable future. Not all clients can also act as servers. Smartphones are a great example where technical constraints rule out webhooks as a possibility. As technology progresses, new ideas will emerge for how to make real-time communication easier between all kinds of devices.
Chapter 7 recap
In this chapter, we grouped integrations into two broad categories: client-driven and server-driven. We saw how APIs can be used to provide real-time updates between two systems, as well as some of the challenges.
The key terms we learned were:
- Polling: Repeatedly requesting a resource at a short interval
- Long polling: Polling, but with a delayed response; improves efficiency
- Webhooks: When the client gives the server a callback URL, so the server can post updates in real time
- Subscription webhooks: Informal name for solutions that make setting up webhooks automatic
In the final chapter of this course, we look at what it takes to turn an API design into working software.
Published in April 2014; last updated January 23, 2024