Not long ago, servers ruled the land of web applications. They stood tall, rendering screens for their users and offering up gigs of processing power to perform actions. You went to a URL, and that server gave you everything you needed. It would do its work behind the scenes while you clicked through a series of screens. But then the single-page applications (SPAs) came and unseated these behemoths. Everything was handled through one URL. Server-side-rendered websites were considered obsolete, a relic of a bygone age. But are they really relics? Are SPAs the next evolution of all web applications? Absolutely not. Let's talk about what server-side-rendered websites are and why they're still useful.
The Lay of the Land
Many server-side web technologies share a set of common components and relationships. There's always some variation, but the diagram below shows what makes up your standard server-side rendering framework, centered around the MVC pattern. (I'll summarize each component.) Now, this doesn't describe all server-side frameworks out there, but popular ones such as Spring MVC and ASP.NET fit this bill.
The router is commonly a front controller, taking in an HTTP request and converting it into the correct controller method to call. It also binds the request's information into the request's input model. This is where a lot of cross-cutting middleware goes, such as authentication strategies and logging. This is also where non-controller resources, such as CSS and static HTML pages, are handled.
This is the core unit of work for a web request. The controller's main goal is to map one or more URLs to an executable model. It takes an input model representing the HTTP request and URL, and then it either changes state if it's a POST request or it returns data if it's a GET request. Ideally, these are fairly skinny, delegating most work to the model. There are usually pre- and post-request hooks that you can wire up for cross-cutting concerns, such as authorization and setting up database transactions.
The model is the meat and potatoes of the system. The goal here is to do the real work. It's as simple as that.
This is the page that the user will see. It renders the model as a browser-readable page, usually HTML. It's often rendered via a template engine with its own syntax, such as Razor.
Where Server-Side Wins
Now that you understand the components of server-side rendering, let's dive into why it still has value. Even though SPAs still have a fading "cool factor," server-side rendering offers up some things out of the box that are unmatched.
Server-Side Lets the Browser Do Its Job
We have a wonderful device that can access billions of pieces of information. It can render and process millions of different tasks of varying categories. It puts thousands of relaxing games at our fingertips. And gee, golly, it's free! It's our web browser. These beautiful beasts are feature rich and let us build content across any industry that's accessible to our customers. Why would we take all this hard-earned effort and throw much of it down the drain? This is what many SPAs do! Browsers have quite a few standard features. For one, they're really good at rendering HTML. They're also fairly good at caching static assets, making our web browsing experience fast. And they automatically support backward and forward navigation. I can bookmark and continue any step in a workflow, such as saving my shopping cart before I place an order. When I render on the server side, I get all this for free. However, most SPAs fail to use these features out of the box. It's common to find SPAs that actually have less functionality than if you just spit an HTML form onto a page.
It Enables Developer Success
Server-Side Is Not Resource-Constrained
SPAs run mostly on your web or mobile browser. This means their power is limited to the power of your device. Although this power increases every year, it's still much smaller than what a server can provide. Server-side rendering lets you take full advantage of the scaling and computation power needed to get the job done.
The PRG Cycle
One of the beautiful guardrails of server-side rendering is the POST-REDIRECT-GET pattern. This pattern dictates all workflows should follow this flow:
You GET a page, looking at the data to make a decision.
You make your decision, submitting a form and POSTING that form to the server.
The server processes the form and REDIRECTS you to a new GET, starting the process all over. This can include the original GET with input validation errors.
Separate Commands and Queries
In software, there's a principle called command-query separation. It also has a big sister named command query responsibility segregation at the system level. Server-side rendering encourages us to use the POST-REDIRECT-GET pattern, which naturally follows these principles.
Cross-Cut Where You Can
I love the idea of filtering out all infrastructure concerns until my model is only focused on the business problem at hand. This is powerful and lets us set up conventions to write code for new features incredibly fast. These cross-cutting infrastructure concerns include things like starting and committing database transactions, logging requests, authenticating users, instrumenting metrics, and more. In server-side rendering, there usually two main places you can add these concerns: middleware and the request pipeline.
The router usually has a place to put middleware, where you can pass the HTTP request through a pipeline of behaviors, a la the chain of responsibility pattern. Cross-cutting concerns that span across both our controllers and static assets are appropriate to go here. HTTPS redirecting and user authentication are good examples.
As I stated earlier, most server-side rendering frameworks support pre- and post-controller action behaviors. This is the perfect place to put cross-cutting concerns that are specific to the nature of your business logic. Database transaction and unit of work management are great here, and so is logging.
Though it's been around for a while and has faded into the backdrop of discussion, server-side rendering isn't dead. It's still very powerful. Single-page applications have a place too, but they don't belong everywhere. If you've never built a server-side rendering application, I encourage you to give it a try. You may be shocked to find how easy it makes your job and how healthy your system looks.