What is this whole architecture about?

I'm pretty sure you must have heard about architects. Well, not those that specialize in designing buildings but those that design IT systems. The name actually is not accidental here because developing software is quite similar to building houses in various aspects and required roles.

You can also compare developing software (that starts with proper architecture) to building constructions from LEGO bricks. Nowadays, there are a plethora of tools, frameworks, services and approaches you can choose from. Imagine all those are LEGO bricks. When starting a project, you are faced with a dilemma of which bricks to choose.

lots of random lego bricks

Now, it is the architect's role to find the proper bricks and create instruction on how to combine them together to deliver the expected value. You pick the wrong brick and sooner or later the construction will fall down. And that's only part of the fun. Ideally, you also should be able to interchange those bricks or add new ones to let your construction grow. Yeap, I know, no one said the life of an architect would be easy.

The ultimate headless architecture

Well, let me be honest with you: there's no such a thing as the ultimate architecture, be it headless or any other. But wait, didn't I name the article "The ultimate headless architecture"? Don't blame me, I'm pretty sure it is neither the first nor the last clickbait you have been poached with. And that's not my fault, it's just that every customer's needs are unique and the combination of required services is unique too. Hence, as a consequence, each architecture is unique.

But fear not. It's hard to explain any architecture looking at super complex diagrams. Instead, we can start simple and focus only on the content part. That should no longer be that scary. Then, we can just keep adding the bricks to let our architecture grow. It's nothing different from a LEGO set, you never start with the last page of an instruction. You start with the first one. And that's what we are going to do in this article.

The headless set of bricks

Let's agree that in this article we will focus on the web channel. You may feel disappointed, but most customers start (and finish) with the web channel, which is still the most important one these days. And secondly, it should not be that hard to extend the architecture to other channels if you know how to deal with one of them. As much as possible, I tried to keep the description channel-agnostic, though.

If you review all the bricks out there, you will find out that to build our LEGO set we need only three of them. These are:

  • Headless CMS - your content platform
  • Code repository - the place you keep the source code of your application (web in our case) - the missing "head"
  • Hosting platform - the place to serve your application from

Please note: it doesn't matter what vendor you choose for hosting, headless CMS, or code repository. The bricks still will be of the same shape only the colour (or their shade) may change.

Ok, so we've picked the bricks, but that's only the start. The way you combine the same LEGO bricks can give you completely different results. You can either use the trial and error method or you can use building instructions. The former may seem to be more fun, but you may need to rebuild it a few times. The latter, on the other hand, guarantees your construction will look exactly as promised, and the fun depends on your attitude! So without further ado let's see what instructions we have.

Note: Next to each method's name in the brackets I put the name specific for the web channel

  1. Static build time delivery (Static Site Generation - SSG)
  2. Dynamic on server delivery (Server-side rendering - SSR)
  3. Dynamic on device delivery (Single Page Application - SPA)
  4. Hybrid static/dynamic delivery (Incremental Static Regeneration - ISR)

Non-technical explanation

IMPORTANT NOTICE: a few paragraphs down you will find a very technical, developer-friendly description of those instructions with proper diagrams. However, personally, I love to be a link between the IT world and the world of non-technical people. To make it more approachable for less technical readers, let me first explain those instructions in a simplified way.

Let's use the LEGO analogy again, but in a slightly different context. Imagine you have a warehouse full of LEGO bricks, but you want to sell LEGO sets to your customers. So, you set up a store. Here are the business models you may want to consider.

Static build time delivery a.k.a. “I have ready LEGO sets for you” business model

Let's assume you know what kind of LEGO sets are popular at the moment, e.g. LEGO Castle or LEGO Pirates. So, you collect all the required bricks and pack them in advance into shiny boxes. When a customer arrives at your store, they can pick a ready set, pay for it and leave. They have been served quickly and they are happy.

Dynamic on server delivery a.k.a. “Let me create a favourite LEGO set for you” business model

But what if your customer is particularly demanding and when they arrive at the store, it turns out all the sets are passé now? What would you do? Get rid of all the sets in front of the customer, go to the warehouse and prepare a bunch of new LEGO sets from which they can choose their favourite one? No, it wouldn’t look professional. But, you already know what is trending now, so you can quickly assemble a new set for the customer. Well, of course, the customer will have to wait a bit until you pack all the bricks. Still, they will be served with what they really want. Because you already know what sets are trending now, you can assemble more of those. Next time a customer comes you are ready and you can serve them quickly.

Dynamic on device delivery a.k.a. “DYI” business model

Now imagine you never know what your customers may want, so you do not prepare any LEGO sets in advance. Instead, when a customer arrives, they can pick all the single bricks they want and assemble the LEGO set of their dreams by themselves. Well, of course maybe they won’t be served quickly, and perhaps they may pick more bricks than needed. On the other hand, running such a store should be pretty cheap, as you do not have to pack the LEGO sets by yourself, and you can spend the time on something more productive, maybe better enjoy your customers.

Hybrid static/dynamic delivery a.k.a. "If you don't find your favourite LEGO set, I will do it for you" business model

Let me put it simply. It's just the combination of the first two business models. Give your customers a promise, they can pick a ready LEGO set or, if they don't find what they are looking for, you can prepare something for them on the fly.

Technical explanation

If you feel like you are ready for something more technical, keep reading.

Static build time delivery (Static Site Generation - SSG)

The artefacts (things that deliver the content to your users - pages in the context of the web channel) are generated in advance before they are even requested by end-users. They are generated at timed intervals or based on some event e.g. code push, content changes etc.

Static build-time delivery architecture diagram styled as lego instructions. A Headless CMS, a code repository and a hosting service are pictured. A developer, a content editor and an end user are represented as minifigures. The code repository pulls content from the headless CMS and pushes it to the hosting service. The hosting service and the headless CMS are not directly connected. Read on for a detailed description of the information flow pictured.

Typical SSG update cycle

  1. Content editor creates content in headless CMS
  2. Either due to content changes, on schedule, or due to changes in the application's codebase, your CI/CD (Continuous Integration and Continuous Delivery) build is triggered
  3. CI/CD starts building pages
  4. CI/CD pulls content from headless CMS to statically generates pages
  5. CI/CD uploads generated pages to your hosting solution
  6. The end user requests a page
  7. The page is either served from CDN's cache (depending on the caching policy) or, if not yet available there, requested from the static hosting

Note: you don't need a CDN, it is just that it gives you so many benefits that it would be shame not to.

When to use

Imagine two sliders. One controls the number of pages and the other frequency of updates. This is the main factor one should consider.

Two sliders: one with number of pages and the second one with update frequency. The former slider is set more on the right symbolizing a higher number of pages whilst the latter one is set more on the left symbolizing infrequent changes

The more you go right with the first slider the more you should consider going to the left with the second slider. Why is that? Because SSG generates the whole app each time it is built so the more pages you have the longer it takes to regenerate them.

When you start paying more for your CI/CD than you would pay for on-demand generation (see next instruction), or you lose money because your content is too often stale for end-users, then you should consider a different approach.

Pros:

  • hosting - statically generated pages are cheap and simple to host
  • performance - statically generated markup is fast to serve and render in the browser
  • secure secrets - your tokens and secrets are never exposed as they are used only on the backend
  • SEO - statically generated markup is more easily digestible by search crawlers. What's more, it's much faster to index than content generated by JavaScript. This translates to SEO benefits

Cons:

  • generation time - it takes time and resources to regenerate pages, which can be problematic with frequent content changes and lots of pages to generate
  • stale content - until you build your artefacts again your users will see stale data
  • process - if your artefact is a native mobile app then updating it and publishing to e.g. Google Play Store or Apple's App store takes a significant amount of time (it can take even more than 24 hours!)

Dynamic on server delivery (Server-side rendering - SSR)

The artefacts are generated on demand when they are requested for the first time by an end user.

Dynamic on-server delivery architecture styled as lego instructions. A headless CMS, a hosting service and a code repositories are represented as boxes. Minifigures represent a developer, a content editor and an end user. The hosting service uses both the CMS and the Code repository while the latter two are not interconnected. Read on for a more detailed description of the data flows.

  1. Content editor creates content in headless CMS
  2. Developers push codebase changes (this can happen anytime)
  3. End user requests a page
  4. The page is either served from CDN's cache (depends on caching policy) or, if not yet available there, requested from some computing services (this can be either lambda functions or some server resources)
  5. Computing services pull both content and code of the application to generate output markup of pages, which are then returned to the end user

Note: CDN is highly recommended here otherwise every request would consume server resources which are expensive in comparison to static hosting.

When to use

Look at these virtual sliders again. If you move the pages slider to the right (you have more and more pages) and you move the frequency slider to the right (you want to update more and more frequently), you may end up with constant regeneration to ensure your users are not served stale content. In other words, if your content changes often or the content cannot be known during the build time, then this method is perfect for you.

Pros:

  • reactive - depends on your caching strategy, but in general, your content is considered always fresh / no stale content
  • performance - statically generated markup is fast to serve and render, however, unlike with SSG we may experience a few milliseconds of delay with the first uncached request (that's formally called latency)
  • SEO - similar as with SSG

Cons:

  • cost - more expensive due to server services required
  • external caching such as CDN is highly recommended (not only optional)
  • page latency - if the page is not yet in the cache, it will take a few more milliseconds before it's generated
  • error rate - depending on your setup, e.g. lambda functions vs server, the the error rate is potentially much higher than with SSG
  • higher quota on headless CMS API is needed because you are going to query the content more often than with SSG. It's not about the performance, because all the major headless CMSs serve content through their own CDN, but even though the traffic goes through the vendor's CDN it's billable per request.

Dynamic on device delivery (Single Page Application - SPA)

The end user downloads a client-side application. When the application is launched / web page opened, a request or series of requests is made to the headless CMS for the content. The artefacts are generated on the end user's device (be it web pages, mobile app views or anything else).

Dynamic on-device delivery architecture styled as lego instructions. A content editor, an end user and a developer are pictured as minifigures. Data requests from the end user reach the headless CMS directly. The user also requests pages from the hosting service. Code is pushed from the repository to the hosting service. Read on to understand the entire flow.

  1. Content editor creates content in headless CMS
  2. Developers push codebase changes (this can happen anytime)
  3. CI/CD starts building the application (note that it builds only the application, not pages)
  4. CI/CD uploads generated application to your hosting solution
  5. End user requests for a page, but downloads only the artefacts responsible for launching the application (from static hosting through CDN)
  6. The application launched on end user's machine requests for content and generates markup of pages

When to use

This kind of architecture is a best fit for app-like websites (usually behind a login screen), e.g., dashboards, admin panels, widgets etc. Another common use case is to render user-specific content. It can be used for regular websites, however SEO and client-side performance will suffer a few precious points in search rankings, if not properly treated.

Pros:

  • simple - the architecture and flow are very simple
  • hosting - statically generated app is cheap and simple to host
  • reactive - your content is always up-to-date

Cons:

  • higher quota on headless CMS API needed - because every request for content always goes to the headless CMS
  • SEO - heavy JS applications are more challenging for search crawlers
  • performance - Single Pages Apps, when already loaded by the browser, are very fast. However, the first (initial) load takes more time and resources, which can also impact your SEO rankings.
  • secure secrets - all the logic is implemented and executed client side. Hence, without introducing a middle layer, you won't be able to hide any secrets or tokens.

Hybrid static/dynamic delivery (Incremental Static Regeneration - ISR)

Hybrid delivery allows having the best of both worlds of the Static and Dynamic on server approaches. This approach is about generating artefacts during the build time, but allowing for dynamically rebuilding them either after some period of time, or on-demand. Here, rebuilding is not that expensive, as not the whole application is rebuilt, but only parts of it.

Hybrid static/dynamic delivery architecture styled as a lego instructions. A headless CMS, a hosting service and a code repositories are represented as boxes. Minifigures represent a developer, a content editor and an end user. Both the hosting service and the Code repository pull content from the headless CMS. The hosting service also pulls code from the code repository to build pages using compute services. Read on for further explanation.

If you look closely at the picture above, you should see similarities to other, previously described instructions. As an exercise, try to analyse the flow on your own.

When to use

A perfect use case is when most of your pages are known during the build time and it's highly unlikely that they will change. Or maybe you know they will change, but very seldom, or that only a limited subset of them will be affected.

Conclusion

As you can see, if you focus only on a single problem, the architecture for it will be simple. If your problem seems to be too hard to solve, always try breaking it down. And the last word, do not limit yourself. If you have ever built anything from LEGO bricks, I'm pretty sure you then dismantled it and built something again, but differently. Try the same with the above instructions. Why don't you combine a few approaches for the same problem? Maybe parts of your website are perfect candidates for Static build time delivery whereas others are ideal for Dynamic on-device delivery? Feel free to experiment. That's why someone invented LEGO bricks after getting bored playing with a "monolithic" toy...

Batman photo by Studbee on Unsplash

LEGO street photo by Alphacolor on Unsplash

Random set of LEGO bricks photo by Rick Mason on Unsplash