10 Tips For Building SSR/HDA applications

Carson Gross

Building web applications using traditional Server-Side Rendering (SSR) or, saying the same thing another way, building Hypermedia-Driven Applications (HDAs) requires a mindset shift when compared with building web applications with Single Page Application frameworks like React.

If you come at this style of development with an SPA-engineering hat on, you are likely to be frustrated and miss out on many advantages of this particular architectural choice.

Here are 10 tip to help you make the mental shift smoothly, taking advantage of the strengths of this approach and minimizing the weaknesses of it:

#Tip 1: Maximize Your Server-Side Strengths

A big advantage of the hypermedia-driven approach is that it makes the server-side environment far more important when building your web application. Rather than simply producing JSON, your back end is an integral component in the user experience of your web application.

Because of this, it makes sense to look deeply into the functionality available there. Many older web frameworks have incredibly deep functionality available around producing HTML. Features like server-side caching can make the difference between an incredibly snappy web application and a sluggish user experience.

Take time to learn all the tools available to you.

A good rule of thumb is to shoot to have responses in your application take less than 100ms to complete, and mature server side frameworks have tools to help make this happen.

#Tip 2: Factor Your Application On The Server

Server-side environments often have extremely mature mechanisms for factoring (or organizing) your code properly. The Model/View/Controller pattern is well-developed in most environments, and tools like modules, packages, etc. provide an excellent way to organize your code.

Whereas SPAs user interfaces are typically organized via components, hypermedia-driven applications are typically organized via template inclusion, where the server-side templates are broken up according to the HTML-rendering needs of the application, and then included in one another as needed. This tends to lead to fewer, chunkier files than you would find in a component-based application.

Another technology to look for are Template Fragments, which allow you to render only part of a template file. This can reduce even further the number of template files required for your server-side application.

#Tip 3: Specialize Your API End Points

Unlike a JSON API, the hypermedia API you produce for your hypermedia-driven application should feature end-points specialized for your particular application’s UI needs.

Because hypermedia APIs are not designed to be consumed by general-purpose clients you can set aside the pressure to keep them generalized and produce the content specifically needed for your application.
Your end-points should be optimized to support your particular applications UI/UX needs, not for a general-purpose data-access model for your domain model.

#Tip 4: Aggressively Refactor Your API End Points

A related tip is that, when you have a hypermedia-based API, you can aggressively refactor your API in a way that is heavily discouraged when writing JSON API-based SPAs. Because hypermedia-based applications use Hypermedia As The Engine Of Application State, you are able and, in fact, encouraged, to change the shape of them as your application developers and as use cases change.

A great strength of the hypermedia approach is that you can completely rework your API to adapt to new needs over time without needing to version the API or even document it.

#Tip 5: Take Advantage of Direct Access To The Data Store

When an application is built using the SPA approach, the data store typically lives behind a JSON API. This level of indirection often prevents front end developers from being able to take full advantage of the tools available in the data store. GraphQL can help address this issue, but comes with security-related issues that do not appear to be well understood by many developers.

When you produce your HTML on the server side, on the other hand, the developer creating that HTML can have full access to the data store and take advantage of, for example, joins and aggregation functions in SQL stores.

This puts far more expressive power directly in the hands of the developer producing the HTML. Because your hypermedia API can be structured around your UI needs, you can tune each endpoint to issue as few data store requests as possible.

A good rule of thumb is that every request should shoot to have three or fewer data-store accesses.

#Tip 6: Avoid Modals

Modal windows have become popular, almost standard, in many web applications today.

Unfortunately, modal windows do not play well with much of the infrastructure of the web and introduce client-side state that can be difficult (though not impossible) to integrate cleanly with the hypermedia-based approach.

Consider using alternatives such as inline editing, rather than modals.

#Tip 7: Accept “Good Enough” UX

A problem many SPA developers face when coming to the HDA approach is that they look at their current SPA application and imagine implementing it exactly using hypermedia. While htmx and other hypermedia-oriented libraries significantly close the interactivity gap between hypermedia-based applications and SPAs, that gap still exists.

As Roy Fielding said with respect to the web’s REST-ful network architecture:

The trade-off, though, is that a uniform interface degrades efficiency, since information is transferred in a standardized form rather than one which is specific to an application’s needs.

Accepting a slightly less efficient and interactive solution to a particular UX can save you a tremendous amount of complexity when building a web application.

Do not let the perfect be the enemy of the good.

#Tip 8: When Necessary, Create “Islands of Interactivity”

At some point in your web application, there may come a point where the hypermedia approach, on its own, just doesn’t cut it.

A good example of this is re-ordering a list of things. This can be done in “pure” hypermedia by clicking up and down arrows or having order # drop-downs next to items. (I am ashamed to admit I have built both of these!)

But this experience stinks compared to what people are used to: drag-and-drop.

In cases like this, it is perfectly fine to use a front-end heavy approach as an “Island of Interactivity”.

Consider the SortableJS example. Here you have a sophisticated area of interactivity that allows for drag-and-drop, and that integrates with htmx and the broader hypermedia-driven application via events.

This is an excellent way to encapsulate richer UX within an HDA.

#Tip 9: Don’t Be Afraid To Script!

Scripting is explicitly a part of the web architecture and developers adopting the hypermedia approach shouldn’t be afraid to use it. Of course there is scripting and then there is scripting.

As much as possible, you should try to use the hypermedia-friendly scripting approach, retaining hypermedia-exchanges as the primary mechanism for communicating system state changes with the server.

Inline-style scripting, as enabled by alpine.js & hyperscript for example, is worth exploring as well, as it refocuses your scripting on the hypermedia (HTML) itself and imposes an aesthetic constraint on just how much code you can write.

#Tip 10: Be Pragmatic

Finally, do not be dogmatic about using hypermedia. At the end of the day, it is just another technology with its own strengths & weaknesses. If a particular part of an app, or if an entire app, demands something more interactive than what hypermedia can deliver, then go with a technology that can.

Just be familiar with what hypermedia can do, so you can make that decision as an informed developer.

#Conclusion

Hopefully these tips help you adopt hypermedia and server-side rendering as a tool more effectively and smoothly. It isn’t a perfect client-server architecture, and it involves explicit tradeoffs, but it can be extremely effective for many web applications (far more than most web developers today suspect) and provides a much simpler overall development experience in those cases.

</>