“Headless Drupal” – If you are more or less seriously involved with Drupal, chances are you’ve observed this trend or even participated in discussions on the topic. It keeps popping up on social media, in blog posts and during Drupal events around the globe. It’s nothing short of a pandemic. An increasing number of presentations and birds-of-a-feather sessions at DrupalCons and DrupalCamps alike are attracting more and more human beings to spread it even further: By now, surely every other local user group has seen a presentation during one of their meetups and there is even a groups.drupal.org group dedicated to it.
At the time of this writing, a huge part of the community has discovered Angular and/or combinations of Backbone, Ember, Mithril and others. One can only imagine the impact that React will have once it becomes more popular in the Drupalverse.
What does “Headless Drupal” mean?
Before we continue, let’s examine what we are talking about. Simply put, “headless” is the idea of decoupling the frontend and the backend. Instead of generating a themed representation of your website, you are providing an interface for extracting pure, uniform data, e.g. JSON, which can then be transformed and rendered independent from the backing application (Drupal in this case).
This blog post is targeted at the client side or server/client isomorphic Javascript driven flavor of what I consider “Headless Drupal”. Of course, you could also say that a static site generator using Drupal as a data hub is “Headless Drupal”. I am sure there are other valid interpretations as well. Also, we are talking about fully headless websites here. If your website contains some arguably decoupled components driven by a subset of the aforementioned libraries and frameworks then that’s not what I understand as “headless”. You can call that “earless” or “eyebrowless” or even “cheekboneless” if you like. When I talk about “headless”, it really means “headless”… All the way.
Why are we experiencing this recent hype?
While the idea of “Headless Drupal” is certainly not new, the WSCCI (Web Services and Context Core Initiative) and its outcome plays a major role in the recent hype. This is how it describes itself:
The Web Services and Context Core Initiative (WSCCI) aims to transform Drupal from a first-class CMS to a first-class REST server with a first-class CMS on top of it.
There is no doubt that the WSCCI initiative is a great undertaking and has produced wonderful advancements that will greatly impact our daily work with Drupal. In Drupal 8 we will be able to build on a thoughtfully architected Router and Serialization API as well as other subsystems like the Entity- and the Typed Data API that are much more sophisticated than their Drupal 7 counterparts. I bow to the fine folks of the community who have made this possible.
When the REST module and the Serialization API finally made their first appearance in Drupal 8, a series of rejoicing blog posts appeared on the web, heralding the era of “Headless Drupal”. There was very little push back or any form of grounded, rational evaluation of the situation and I can’t deny that I was equally, if not more excited about the seemingly endless possibilities that suddenly emerged on the horizon.
Rationalism was being drowned in a huge wave of hype. There was little push back apart from some critical or annoyed Tweets. Looking at it now, the most disturbing part of this ongoing hype is that people suddenly advertise and talk about “Headless Drupal” as a replacement for the built-in Drupal theming layer. No more heavy markup, no more useless divs and classes and certainly no more “The Angry Themer” talks from Morten. It sure sounds nice. But it’s not that simple. It really isn’t.
I hate to spoil the party, but here’s the truth: If you expect to be able to build your next project by simply configuring a few resources and putting together some React components or Angular directives you’re in for a disappointment. It’s going to take a little bit more than that.
Are you ready to do without your favourite features?
Drupal 8 is going to be an immensely powerful CMS. A huge part of the success of Drupal stems from its enormous potential for customization. Drupal has a long standing tradition for enabling a very broad audience to build even complex websites simply through configuration in the backend. It also comes with a very sophisticated multilingual system for both, the content and the interface. I think we can all agree that there are many good reasons for choosing Drupal.
It is important to realize that many of these are, at least partly, nullified once you make the move towards headless.
MULTILINGUAL
Fetching the content in the right language is not a big deal. However, since you do not have access to Drupal’s string translation, which is also not desirable, you will have to take care of translating the interface yourself.
MODIFICATIONS AND ONGOING MAINTENANCE
All modifications you make to your data schema or user interface are most likely going to require changes to your code on both sides of your application. Many of the configurations on the backend become insidious because they will have zero effect on the frontend. Sitebuilding is pretty much reduced to setting up the data schema and access levels.
EDITORIAL USER EXPERIENCE
It’s unlikely that you will have any linking between your backend and frontend making editorial tasks cumbersome.
ACCESSIBILITY
As @_nod points out (thanks!), a lot of effort has been put into making Drupal 8 as accesible as possible. Once you drop the native Drupal rendering and theming layer you will have to take care of this yourself. Crafting a truely accessible website can be really challenging and there are lots of things that can be easily missed.
This is just a short list and there are definitely more things that you will have to wave goodbye.
There are more universal challenges too
OVERALL PERFORMANCE
This is a huge problem. For a structurally simple website this probably doesn’t hit you as hard. You can always use very sophisticated caching strategies, too. However, it is undeniable that you are producing a considerable overhead through the amount of additional roundtrips to the server. When using standard REST resources you are going to need multiple requests at least for the initial rendering of the page. You are going to see your browser stuttering as it spits out one piece of the website after the other as it receives the requested data one response at a time.
Even subsequent routes are likely to produce more than one request to the server. This all comes at the expense of performance both on the server (extra bootstraps) and the client (extra requests that are potentially even blocking each other).
APPLICATION SIZE AND COMPLEXITY
Building a complex application in Javascript is not easy. The Javascript file size for a moderately large application can easily reach a couple megabytes. Structuring the application properly and consistently and a proper fragmentation strategy for lazily loading the required Javascript on demand is non-optional. This requires significant experience in and a deep understanding of the problem space.
JAVASCRIPT DEPENDENCY
In the worst case scenario you would impose a client-side Javascript dependency on your users. This is not so much of a problem itself given that search engines are becoming better and better at properly analyzing Javascript driven websites, however, this means that you are now relying on the browser for the rendering of your application. This is bad. Browsers change and so does Javascript. Future versions of your favourite browser might, at some point, drop support for some functionality you are relying on. You can mitigate this problem as well as sluggish, initial rendering of your application by making it isomorphic.
You see, it is not all rainbows and unicorns. Building a truly functional and user-friendly experience with a completely decoupled user interface is hard and demands extensive planning and research of the different solutions for the aforementioned problems.
One of the harder problems: Traditional REST is a dead end
You might find this rather ironic considering that the development of the REST module was one of the key factors that sparked this hype.
However, for a fully decoupled, highly interactive front-end solution for your application, traditional REST and plain entity schema backed resources won’t cut it. I am assuming that in most of these cases your data will be highly relational. Rendering related views with interdependent data requirements will inevitably result in an ever growing number of requests or exponentially increasing complexity of your custom tailored resources which, at that point, probably can’t be called RESTful anymore anyways.
Assuming that you want to keep your resources as agnostic and modular as possible (after all, one of your goals was to decouple the whole thing, right?) you are going to run into performance problems both on the client as well as on the server.
First of all, each browser implements a different limit of parallel HTTP requests per server. The original HTTP/1.1 RFC suggested a limit of 2. While in reality this limit is much higher in modern browsers (Chrome, for example, now allows 6 parallel connections) it is still something to keep in mind. Blocking HTTP requests are nasty. Especially considering that things like images and other assets fall under this rule as well. You can somewhat mitigate this problem by moving your assets to a CDN and using wildcard subdomains. Keep in mind that this will affect your client-side caching.
Blocking HTTP requests will make your application feel extremely slow and completely undermine your user experience, no matter how much work you put into your user interface. This especially affects the initial page load when each of the pieces with data needs is rendered one after the other as the data flows into your view.
But putting aside browser HTTP request limitations, there is still the more serious problem that multiple separate requests will all cause independent bootstraps on the backing application and we all know that Drupal is not particularly famous for it’s shallow bootstrap.
This one is tricky.
There might soon be solution to this problem
What if you could accumulate the data needs for all of your views and express them as a single query that runs through a single, shared resource on your backend. What if that resource could then resolve the query into a set of specific root calls that then get processed accordingly before they are merged back together as a single, structured response?
Two months ago Facebook announced that they are going to release a new client side library called Relay as well as a specification and reference implementation of a DSL called GraphQL.
While neither the specification, nor any of the reference implementations or Relay are publicly available yet, Facebook is providing us with a constant stream of informatino through various different channels. Based on this information, I’ve started working on a few things including a GraphQL Lexer and Parser in PHP5 and, specifically for Drupal, a Content Entity adapter built around a more generic Typed Data adapter.
I am going to write a more in-depth blog post about this specific undertaking once I am comfortable making it public on GitHub and drupal.org. The Drupal specific adapter will be hosted at http://drupal.org/project/graphql.
No comment yet, add your voice below!