[SDKs & UI Libraries] The Backend-Driven UI
With this post, I’m continuing publishing the v2 of my book dedicated to APIs. If you like this book, please rate it on GitHub, Amazon, or Goodreads and
Another method of reducing the complexity of building “bridges” that connect different subject areas in one component is to eliminate one of them. For instance, business logic could be removed: components might be entirely abstract, and the translation of UI events into useful actions hidden beyond the developer's control.
In this paradigm, the offer search code would look like this:
class SearchBox {
…
search(query) {
const markup = await api.search(query);
this.render(markup);
}
…
}
Instead of receiving machine-readable search results, SearchBox
gets a ready-to-use representation in the form of HTML code or other declarative markup (possibly developed specifically for the SDK).
This approach could be abstracted even further:
class SearchBox {
constructor (…) {…}
stateChange (patch) {
// `SearchBox` receives a list
// of actions to perform in response
// to any state change
let actions = await api
.getActions(
this.model,
patch
);
// Performing the actions
…
}
}
In this code sample, it is implied that SearchBox
doesn't contain any logic at all except for sending events that happened to it (i.e., the user's or the developer's action) and displaying the content sent by the server.
(So-called “Web 1.0” is a fine example of this approach: the server always sends full ready-to-use page content, and the interactivity is limited to traversing hyperlinks.)
The backend-driven UI approach has obvious problems as it requires a fast and stable connection to the server. However, it is still appealing to developers because of two advantages:
The ability to fully determine clients' behavior, including fixing mistakes in business logic in real-time without the necessity to publish new application versions.
The ability to skip developing consistent and readable SDK entities nomenclature by providing a very limited set of functionality.
Nevertheless, we cannot help but state the fact that despite all big IT companies passing the stage of developing backend-driven UIs (aka “thin clients”) for their applications and public SDKs, we cannot name a single notable product developed in this paradigm (except for protocols for remote terminals), although in many cases the arising latencies could be ignored. We would take the liberty to say that this situation has developed because of the following reasons:
Developing server-side code for controlling a UI is never easier than the client one.
Modern client devices provide a broad range of functionality only a client code has access to, from caches to animations.
Writing hybrid code that partially receives the state from the server and enriches it with client-only functionality is more complex than writing pure client code (as in the backend-driven UI approach, the response of the server is a “black box,” interacting with which requires inventing additional protocols).
Not writing hybrid code means, firstly, reducing the capabilities of applications, and secondly, actually using a device in a “cloud gaming” mode, which is quite expensive and not very convenient to the user as of today.
Currently, developing backend and frontend code are two different specializations requiring different expertise and approaches to writing code.
NB: the backend-driven UI should not be confused with server-side rendering (SSR). The latter implies that a specific UI state (in the form of HTML markup or similar declarative description) could be generated both by the server and the client. The difference is that in SSR, clients are typically able to parse the response of the server and extract semantic data.
From the perspective of providing SDKs to external developers, the backend-driven UI approach forces writing hybrid code (as the practice of allowing partners to inject their code in the server rendering functions seems non-viable as of today) and therefore suffers from the non-transparency problem as developers won't be able to determine the state of the visual component. Ironically, this impairment is at the same time an advantage as the API vendor retains the possibility of manipulating the component's content without breaking backward compatibility (we will discuss this in more detail in the “API Services Lineup”). There are many public APIs in the world that operate in this paradigm (starting with advertisement networks inlets, various widgets, etc.), although we wouldn't call them fully-fledged SDKs.
This is Chapter 46 of “The API” book being written by Sergey Konstantinov. I also have a book on the history of beer and historical beer styles, a Telegram channel on interesting classical music recordings, a travel photo blog on Unsplash, and a website with ranking fantasy & science fiction novels based on awards they received.