Why Aren’t APIs Using Code on Demand?
Why aren't APIs taking advantage of code-on-demand, one of the constraints of REST?
If you're reading this article on a Web browser, you're experiencing the effects of code-on-demand. The whole Web runs on the premise that clients can not only request data but also code they then run to manipulate the information they receive. A common approach is to run JavaScript on the browser to provide users with a complete experience involving data and business logic. Why aren't APIs following a similar approach? Stay with me.
This article is brought to you with the help of our supporter: Speakeasy.
Further expanding its best-in-class API tooling, Speakeasy now empowers teams with open standards. The platform simplifies OpenAPI Overlay adoption so you can focus on building. Click the button below to check out the playground.
A few days ago, while doing some research for a project I'm working on, I ended up re-reading Roy Fielding's famous REST dissertation. However, this time, my eyes stopped when I read "code-on-demand." Not once, not twice, but a few times throughout the document. Fielding defends that code-on-demand offers "the ability to add features to a deployed client" offering better user-perceived performance. He makes code-on-demand one of the constraints of REST, albeit an optional one. According to the dissertation, code-on-demand "simplifies clients by reducing the number of features required to be pre-implemented." It looks like using code-on-demand is something everyone should be doing.
The notion of code-on-demand isn't something that Fielding came up with. As I wrote before, most Web applications rely on it to create the perception that interaction is local. Before that, every interaction was converted into a request sent back to the server. Web browsers would then render the response back to the user and wait for another interaction. The whole experience, from a user perspective, consisted of a series of requests with subsequent responses that eventually led to the rendering of a new Web page. And this is pretty much how REST APIs feel like today.
There's, of course, a huge difference between the Web and REST APIs. While the Web has a uniform—mostly, depending on what compatibility you're looking for—client, REST APIs don't. The browser is what makes it possible to offer a common set of features across the whole Web. It doesn't matter what Web site you go to, you expect to be able to access it with your browser of choice. The browser offers a set of common features and libraries that the Web takes advantage of. One of those features is code-on-demand. It works whenever the browser interprets that there's certain content it should execute locally. JavaScript is one example of code-on-demand that browsers understand. One could argue that CSS is another form of code-on-demand because it applies logic—in this case, it's style—to the data the browser receives.
So, how can REST APIs follow a similar code-on-demand approach if there isn't a standardized client? I couldn't find any examples of REST APIs using code-on-demand in the wild. What I found, though, was a way to standardize the API client so it becomes aware of code-on-demand features and is able to execute code locally. Almost by accident, I became aware of HyperMap, "a new format for REST APIs that lets you execute JavaScript and WebAssembly on the client." Wait, what? It works by using the application/vnd.hypermap+json
content type to signal that a response might have code to be downloaded. It also introduces a client called Mech that understands code-on-demand. The Mech client knows if there's code to be downloaded and makes it available to the client. You could implement a similar thing yourself without having to use HyperMap. However, it's interesting to point out that someone is already exploring a viable solution.
In a world where REST APIs follow the code-on-demand approach, many new patterns would become possible. You could, for instance, deliver whole or partial SDKs directly to the client on demand. You could have a "bootstrap" request that would return initialization data and code you could use to fire up your client. You could have clients automatically update themselves according to the latest API version. Speaking of versions, you could deliver breaking changes along with code that would do compatibility translations. I'm sure you would come up with many other ways to use the code-on-demand approach.
What's holding us back, I believe, is the fear that letting clients download and execute code on demand can introduce security risks. That's fair, but I think the benefits of code-on-demand are so great that we should see it as a viable evolution of how we work with REST APIs. A great way to open API consumers and producers to code-on-demand would be to encapsulate the approach on generated SDKs and API gateways. If you happen to be working on one of these areas you should consider at least experimenting with adding the code-on-demand feature.