The Web has gone a tremendously long way since it's conception in 1989. It has progressed to the point where it’s so omnipresent and the user base is so vast that it’s becoming harder and harder to scale and expand existing services to satisfy the ever growing demand. The traditional architecture is starting to show its limitations and suddenly it’s becoming clear that what was considered the way to develop web applications is not going to cut it under the current circumstances.
Also known as the traditional architecture, is what powers the vast majority of what the Web has to offer. It’s the all-in-one bundle of web applications - the backend is tightly coupled with the frontend and the whole app is just one big ecosystem.
For a big chunk of time this approach was the undisputed king of web development. And while it’s without a doubt still reigning and growing steadily, the consumer trends evolve in a direction that makes many service providers reconsider the usage of this kind of tools, namely WordPress.
Back in the day running a website was enough to ensure that you target the majority of Internet dwellers. Nowadays, thanks to some monumental advancements in technology, the users have many more ways to go online - phones, smartwatches, voice assistants, AR glasses etc.
This makes one of the problems very clear - because of how tightly coupled the presentational layer is with the backend logic it’s a major hassle (or downright impossible) to expand the application so it can support more channels than it was originally designed to do.
For example, one could imagine that it would be solvable by running multiple instances of the application, each designed to handle a specific medium. Apart from the obvious development overhead this would generate, managing multiple systems simultaneously would be a major headache - e.g. in e-commerce websites product discounts would have to be entered and synchronized separately for each running instance.
This is especially true for businesses that are heavily reliant on how accessible their web services are, most notably e-commerce websites. Expansion beyond the web is often the key to new market penetration and is often what distinguishes “just” successful ventures from market leaders.
Another thing that caused the shift away from monolithic architecture is the fact that the server would render pages visited by users with each request. This greatly impacts the user experience and makes the website feel less “snappy”.
While this is but a drop in the sea of shortcomings, it’s what widely believed to be the turning point and reason why alternative solutions are gaining traction exponentially.
Despite its buzzwordy status nowadays, the concept of headless software is dead simple and has been around for ages. “Head” in this context means “graphical interface” - you can probably see where this is going. The headless approach completely removes the presentational layer, leaving just the backend logic that can be exposed through a universally accessible API layer.
Instead of a singular, tightly coupled with the logic and heavily specialized frontend, its focused on providing applications with the raw content/services it offers. One of such apps can be responsible for consuming the data and presenting it to the end user.
That’s precisely what’s needed when it comes to building multi-channel applications. Since the presentational layer is completely interchangeable and the core API is universally accessible, there could be multiple entry points interacting with the app, each designed to support a different medium.
Nowadays, a big portion of an application’s features can be extracted to third-party SaaS platforms. Not only does this reduce a product’s time-to-market but, since they usually cover some highly technical features, can also improve the systems overall security. Some of them could be payment gateways, delivery services, ERP systems etc.
The most common monolithic choice on the Web is WordPress - a staple among traditional Content Management Systems. It offers a user-friendly interface for managing content and basic customizability through various plugins. There are extensions providing integrations with the most common of services which could prove sufficient for some very generic applications.
The word “common” was emphasised for a reason though. If the chosen platform doesn’t offer a specific plugin that is required by the project’s requirements, there is no other way but to either write it from scratch (often in some obscure technology) or change the platform. Keep in mind that even the largest of traditional CMSs doesn’t support a portion of the third-party platforms, so you can expect to run into situations where a part of your project’s scope gets blocked by an unexisting plugin.
On the other hand, headless architecture ties in very nicely with external services and applications. As emphasised before, headless benefits greatly by dividing its functionalities between multiple components. To draw comparison with the aforementioned WordPress, we can consider what’s called a headless CMS, such as GraphCMS or Contentful. It provides the same functionality, that is content storage and a user friendly administration panel, without coupling it with any presentational layer and crippling it’s extendability in the process.
At first glance scaling monolithic applications seems trivial - multiple instances of it can be hidden behind a load balancer to scale horizontally. However, as the application grows in size, scaling becomes increasingly difficult and inefficient.
For example, it’s impossible to scale one single part of the application independently. In cases when there are few different bottlenecks scaling the entire system is very cost inefficient.
Moreover, for stateful applications, you have to take user sessions into account and incorporate mechanisms like sticky sessions to ensure that users with existing sessions are routed to the same physical machine each time.
On the other hand, it’s easy to imagine how headless can improve scalability - the application can be divided into autonomous services and scaled independently.
Apart from the obvious structural differences, both approaches differ heavily when it comes to implementation, maintenance and development workflow in general.
Developer teams working on large monolithic applications have to constantly be aware of all the systems components and it’s impossible to work on a single part independently.
Moreover, continuous deployment is, to put it lightly, problematic when working on monolithic apps. With each new release the entire application has to be redeployed. This forces teams working on different parts of the system, e.g. the UI and the business logic, to coordinate their deployments.
On the other hand the compartmentalised nature of headless architecture makes it an ideal choice for teams consisting of multiple developers. Each part of the application can be independently managed, tested and deployed without interfering with the rest of the system.
Jamstack is one of the hottest trends in web development right now. It’s focused on certain assumptions and best practices rather than on certain technologies. The performance and security improvements it brings to the table make it very popular among modern website developers and service providers.
Jamstack stands in complete opposition to traditional, monolithic applications. It shifts the focus from an omniscient, one-man-army backend to lean and powerful frontend. Extracting all logic to external API’s improves the sites overall security by reducing the number of potential attack vectors.
As it happens, Jamstack works hand in glove with headless applications.
Headless + Jamstack in practice
Building Jamstack websites has become very easy since the conception of tools such as Nuxt or Gatsby. They are based on tools very familiar to developers, Vue and React respectively, so they are right there in the comfort-zone.
Such frameworks intelligently build HTML files from templates filled with pre-fetched data so they can be served through CDNs as static assets. This, as one might expect, is a huge boost to the site’s performance, making navigation almost instantaneous. CDN service providers also make it easy to force the use of SSL on your sites (sometimes it’s as simple as flipping a switch), which can otherwise be problematic since, by design, there is no underlying server.
Serving static assets is not that useful if there is no way of populating the site with easily modifiable content. That’s where the aforementioned headless CMS’s come into play. They offer exactly the same content modeling functionality as traditional solutions, such as WordPress, and expose it through a blazing fast API. The chosen Jamstack framework will pre-fetch all the data it needs during the page generation phase and build static HTML files according to the templates that were defined. That’s an ideal setup for websites like blogs or product catalogs, where user interaction is scarce and content serving speed is the main bottleneck.
There is one caveat though - since the pages are pre-generated, they won’t automatically display new content that was created. A good majority of SaaS’s offer a well-known mechanism to automatically trigger rebuilds when a change in content is detected - webhooks. They can be used to trigger production deploys, emails, SMS notifications etc. On most platforms they are completely customizable - the possibilities are endless. By automatically triggering, say, a Heroku or Netlify deployment after changing some data, the website is always up-to-date with the content. One thing to watch out for here is that errors during the build process do not make the process return with a non-zero exit code by default in some frameworks, causing successful deployments despite the failure.
The situation looks a little different when trying to integrate with some obscure API that serves dynamic content, that doesn’t necessarily offer the luxury of notifying you when some change occurs. An example of such service might be a stock management system, basing on which it's decided whether to include a given product in a website’s catalog of available products. It’s possible to work around this by scheduling a redeploy of the website to occur every X minutes/hours. Depending on where the application is hosted, this can be achieved either with some in-built functionality (e.g. Heroku Scheduler) or traditional cron jobs. This solution might be good enough for most services, while others may suffer from the interval during which the site is de-synced.
While they have some clear advantages over monoliths, headless (and Jamstack) applications should be treated more as an alternative than an outright replacement for them. As per usual - it all comes down to a particular use case that’s being implemented. And while the traditional approach appears sluggish and outdated, it’s even worse to dive head-first into new trends without properly studying their limitations.