What we talk about when we talk about server
Related post: “What is a server, anyway?”
The client-server model makes up the very foundation of web, but we web developers often talk past each other when we talk about server. This is particularly unfortunate because server is increasingly an important topic in modern web development.
For web development, I’d like to distinguish two types of servers based on the kinds of requests they’re made to serve: those for tasks and those for content.
The job of the first type of server is to perform a requested task and respond with its outcome. This task can be anything specified in its interface contract: data queries, authentication, validating user input, sending email, making financial transactions, and so on. We normally call this type of server an API server.
The job of the second type of server is to respond with requested content: user interface (documents, stylesheets, scripts) and media (images, audio and video files). The content may already exist in a static form or need to be dynamically generated. In reality, serving up content is just another task, but it’s a special case in web development and a server for this job is often called web server.
Because content is so central to web development, we have much more to say about serving content. For instance, we have specialized computer networks to efficiently handle serving static content, called content delivery networks or CDNs.
While most content is static, one type of content is often highly dynamic: documents defining user interfaces. This dynamism is essential to provide the interactivity and flexibility required for increasingly complex applications running on the web. We often call the work of generating this document rendering.
Traditionally, most rendering happened on the server side, before the finalized document was sent in response. With the growing demand for more dynamic user interface, more of this rendering work moved to the web browser i.e. the client side, and JavaScript UI frameworks to facilitate this became popular.
Rendering the user interface fully on the client side has many limitations, and various techniques are introduced to address these limitations by leveraging the server side. Server-side rendering (SSR) is one such technique: it generates and sends the full document in the initial response so the browser (and the user) can immediately see the complete user interface. The trick here is to include data to recreate the same user interface in the response to allow the UI framework running on the browser can pick up the rendering work after the initial load (aka “hydration”). Another technique is pulling all data requests for a page and handling them on the server side in parallel to avoid unnecessary network waterfalls. Many full-stack web frameworks (aka “metaframeworks”) are created for JavaScript UI frameworks to make these techniques accessible.
Alternatively, there are efforts being made to move UI rendering back to the server side. One approach is to break the user interface into noninteractive and interactive sections, and allow client-side rendering only for the latter, interactive “islands.” A more radical approach is to move all rendering to the server side with support for sending only a partial update to the document in each response and merging it into the current page instead of replacing the whole document.
More recently, we’re seeing a trend toward deeper integration of the server into UI frameworks themselves. Server functions (or remote functions) offer a convenient and type-safe way to define and handle any request to perform some task on the server side all within a framework. Server components, on the other hand, allow a framework to make and handle a request for rendered content on the server side but in a special format intended for the framework code running on the browser, not the browser itself.
As I mentioned, most of these techniques and approaches are about overcoming the limitations of rendering user interface fully on the browser, and this is achieved by moving more work to outside the browser—to server. However, server is not a concrete entity but an abstraction. It’s a name for anything and everything that exists on the other side of the network and responds to its client’s requests, which is often the browser in web development.
So, instead of talking about server as such, we should frame our discussions in terms of server capabilities. That’s what we talk about when we talk about server.