Benjamin Geer

Writing safe hypermedia apps for a resource-constrained world

Benjamin Geer

When I was developing web applications in the 1990s, it was common for the server to generate HTML pages using templates, and a lot of template engines were written for this (including one by me). Starting in the early 2000s, Single-Page Applications (SPA) became widespread. In an SPA, the server mainly returns JSON, and a JavaScript (or TypeScript) framework generates the HTML in the browser. I’ve worked on some applications like this, and it struck me that they’re cumbersome to maintain, partly because the JavaScript frameworks are huge and complex and change rapidly.

Nowadays there is increasing dissatisfaction with the SPA approach, not only because of the maintenance burden, but also because these applications have to load megabytes of JavaScript over the network before they can do anything, and this makes them slow, especially on slow network connections. Meanwhile, HTML has become more powerful, making JavaScript less necessary. As a result, there is renewed interest in generating HTML on the server.

One of the drawbacks of generating HTML on the server in the 1990s was the need to reload the whole page whenever anything changed. Now that limitation is gone, thanks to tiny JavaScript libraries like htmx. By adding declarative attributes to HTML elements, we can allow all sorts of user interactions to fetch fragments of HTML from the server and replace only the parts of the page that need to change. Applications that work this way are called Hypermedia-Driven Applications, and there’s a book about them, called Hypermedia Systems.

The book shows how to construct a contact management application using htmx, and the source code is provided in Python. Since the book’s focus is on htmx, the server code is very simple: it only supports English, contacts are stored in a file rather than in a database, there’s very little input validation, pagination uses page numbers, and there are no tests.

In a resource-constrained world, it makes sense to write applications like this in languages that compile to machine code and use relatively little memory.1 We’d like to have the option of using a very lightweight database like SQLite or a more powerful one like PostgreSQL. To help prevent bugs and security vulnerabilities, we can favour statically typed languages with an emphasis on built-in safety features. And we’d like our application to be easy to maintain.

Given these preferences, let’s make the example app from Hypermedia Systems more realistic. We’ll give it an internationalised UI, a relational database with a full-text search index, better input validation, cursor-based pagination, and UI tests. In the next few posts, I’ll present two implementations, one in Go and one in Rust, with either SQLite or PostgreSQL. I’ll explain the design choices I’ve made in each version, and cover some interesting techniques that have wider applications. I’m not a UX designer, so I won’t try to improve on the user interface described in the book, but I’ll have a few words to say about facilitating the work of UX designers. I won’t cover most of the details that are explained in Hypermedia Applications, but you can read these articles without having read the book. Let’s think about some techniques we can use to write web applications that are safe, resource-efficient, and easy to maintain:

(Each article can be read independently of the other.)


  1. The relationship between energy efficiency and the choice of programming language is an active area of research; see Energy Efficiency of Programming Languages. ↩︎

Categories:
Topics: