DrupalCon Baltimore: Drupal, React and GraphQL
In April last year, Michael Schmid and Brandon Williams from Amazee Labs presented at DrupalCon Baltimore. Their presentation focused on using GraphQL, Apollo and Redux with decoupled React frontend for Drupal.
DrupalCon Baltimore was a five-day Drupal extravaganza in April 2017. And while that’s nearly a year ago (time flies!) Michael and Brandon’s presentation on the future of Drupal is thought-provoking and extremely relevant today. Below is a summary of their talk - with some updates to ensure the blog’s relevance directly from Michael Schmid. You can also view the full presentation on YouTube.
Michael Schmid (CTO) kicked off the presentation, talking about Amazee Labs and some of its history with Drupal. Apart from Drupal, the company tries to explore other innovative technologies and more recently started using React applications with Drupal as a backend. Michael talked about the fact that when the idea of decoupled Drupal was first introduced between 2013 and 2016, Amazee Labs wasn’t a big fan. In the past, they’d stayed away from it because of several concerns:
- Significant initial overhead
In fact, they thought the blog: Black Post – Headless Drupal – The Cake is a Lie captured it well.
However, things changed for Amazee Labs in October 2016, when decoupled Drupal became the solution for one of their clients.
Case study – October 2016
A client wanted to implement 12 different sites powered by the same backend. These sites needed to look and function differently, but use a single content data source. One of the solutions was to create 12 different Drupal themes, but the client also wanted to work with multiple independent development teams. So how could that be done? The answer was obvious enough: decoupled Drupal.
Amazee Labs revisited decoupled Drupal. They did a bit of research and found GraphQL as a possible solution for the commonly known issues described above. After some custom development (which was later open-sourced), they eventually launched the first site that used Decoupled React – www.gaultmillau.ch. The site uses the following components:
The frontend talks to the backend using GraphQL.
At this point, Amazee Labs realised it was finally possible to do decoupled websites well, without compromising accessibility and performance.
GraphQL was introduced by Facebook, who has been using it in its mobile applications since 2012. The schema, idea, and specification of GraphQL were published by Facebook in 2015 and since then it has been widely used in a lot of implementations.
To demonstrate GraphQL, Michael showed a Star Wars API at http://swapi.co and requested some example data from available endpoints:
Request 1: API endpoint – People (https://swapi.co/api/people/)
Request 2: API endpoint – Films (https://swapi.co/api/films/)
Request 3: API endpoint – Species (https://swapi.co/api/species/)
With regular REST API, if you want to get the information about the species of a film that features a particular character, you end up running a lot of different requests. Alternatively, you could ask the developer who created the first endpoint to include the data from the second and the third endpoints instead of having URLs to those endpoints. However, such an endpoint is not dynamic and if a different frontend needs a variation of the same data, a similar REST API would need to be there to provide it. This means that you can end up having a lot of different APIs. GraphQL fixes this issue.
GraphQL ships with a nice user interface (UI) called GraphiQL. The idea is that you not only run queries inside it, but you also learn how your REST API works. On the left side of GraphiQL, you write your query. On the right side is the output.
With GraphiQL, you’ll find yourself using certain keyboard combinations frequently:
Control + Space: gives all available fields (endpoints).
Once you choose a field (endpoint), you can define it by opening a bracket, then Control + Space again to select how to define it (endpoint).
Enter: autocompletes the field (endpoint) with its attributes.
With GraphiQL you can:
Retrieve objects (endpoints) with specific fields.
Establish relationships to other objects (endpoints) that can be fetched within the same request.
Change name keys of object fields (endpoints) as it suits your application. This is done by putting the name you want to appear instead of the original field name prior to the original field name with a colon.
The idea behind GraphQL is that you’re not only consuming API endpoints, but you’re actually telling your API what you want and how you want it to be outputted. In other words, you can define to the object/endpoint what you want to receive as a response. You can also join multiple queries together in a single request.
By using GraphQL you empower the person that actually needs the data to define what they need, what they use, and how they use it.
Some of the key benefits of GraphQL are:
Provides exactly what you need.
Allows you to request/query multiple resources at once.
Features fragments that enable you to inject variables that you use.
Any schema is possible – the person who is writing the GraphQL API can define the fields (endpoints) with complete control.
Mutations – endpoint fields can be requested, created and changed.
Versionless (no versions) – when another field becomes available, it can just be added to the endpoint request.
GraphQL is based on a very strongly typed system with relationships between objects (reference entities). Drupal 8 is also strongly typed so it makes a lot of sense to use GraphQL with Drupal.
Drupal GraphQL Module
Amazee Labs combined efforts with the broader Drupal community to create the Drupal GraphQL Module (https://www.drupal.org/project/graphql), which provides full GraphQL support inside of Drupal. The module is available here: https://github.com/drupal-graphql/graphql.
Usage basics for Drupal GraphQL Module
Learn GraphQL (classic) first (http://graphql.org/learn/). GraphQL syntax and concepts are simple. If you learn the basic concepts, you’ll have all the information necessary to start using the GraphiQL (UI).
Installing the Drupal GraphQL module lets you get the graphical user interface – GraphiQL. With a basic understanding of queries, you can rely on autocomplete to discover available Drupal objects. This will show you how the GraphQL module in Drupal works and what schema it provides.
Brandon had already started writing the GraphQL backend for the Texas Camp website using React for frontend and Drupal for backend. He showed an example of the extensions that he came up with in the process.
The process can be summarised in the following steps:
Define the root query field, in this case it is SectionByNameField
Create SectionType that’s being returned by the root query field
On the section type define what fields are available (body, image, title, etc.)
So essentially it’s just three classes, a little schema glue, and you’ve got data being returned at your GraphQL API.
Drupal GraphQL module
After the GraphQL module had been injected in Drupal, it was deployed in production, though if first seemed not to be completed.
A default schema will be available where all the data can be requested.
You can bring your own schema by having a subset of the default schema available. The idea is that you can install GraphQL module on the Drupal site and everything can be requested.
Content entities and config entities can be requested. Everything that’s accessible through Drupal can be requested using GraphQL.
Full Drupal cache and cache tag support. When GraphQL requests with Drupal module, you get a huge amount of cached tags that you can use.
Mutations are supported. You can create entities by GraphQL.
The presentation then moved onto the frontend.
React: frontend library by Facebook that’s quite widely used.
Redux: Predictable state container used by Apollo that allows you to have different states of your React application and you can jump backwards and forwards using it, knowing exactly what happened. It’s much easier to debug and delivers better performance.
SEO is the process of affecting the online visibility of a website or a web page in a web search engine’s unpaid results - often referred to as natural, organic, or earned results.
Using a regular REST API to load data, you will have a lot of different requests to the backend corresponding to separate endpoints requested one by one. With GraphQL, multiple requests can be done in a single request. React, Apollo, and Redux keep an internal cache of everything that has already been loaded, and because GraphQL can request multiple resources in one single request, it can figure out what’s needed and what isn’t.
In https://www.gaultmillau.ch, the website contains different pages – some of the pages might have a footer with different links, and other pages (like pages containing maps) might not have that footer. Nevertheless, and since the multiple resources are loaded with a single request (GraphQL), all resources will be cached, and if they're needed, they can be easily loaded and displayed.
Back to the initial client’s concept where multiple frontends are connecting to the same backend (Drupal, GraphQL Drupal module, and an express Nodejs server in the hosting environment). There’s a lot of cache data nodes (CDNs) caching the different requests when an initial request is first made and letting all different resources (endpoints) be available for others. CDNs are available on different caching layers, and the GraphQL requests are also cached as all of them are likely to have similar URLs and resources requested.
Everything you need to learn more about this module can be found at https://github.com/drupal-graphql/drupal-decoupled-app.
Amazee Labs made a high initial investment to prove decoupled Drupal can work, and made it easy to use, resolving all the issues of SEO, accessibility, performance and hosting by using GraphQL within the Drupal GraphQL module. All the way, Amazee Labs stayed true to its commitment to open source. This made life easier for developers, who obviously can now use decoupled frontends. The clients are very happy as well, since costs are reduced because they don’t need to pay for every different Drupal site. Instead, they can have different frontends talking to the same backend.
Questions and answers
Why did you choose Apollo over Relay? During the study and the preparation of Drupal GraphQL module, for the first five months Amazee Labs was using Relay instead of Apollo. When Apollo came into the picture, they realised it’s much easier to use and implemented GraphQL since its libraries fully support all features of GraphQL. In Relay, it’s not that straight forward. So they re-engineered the whole thing using Apollo.
About cache invalidation, what happens if the footer changes while it’s cached?Is there any other work around rather than refreshing the page? It hasn’t been decided yet, but some check validation will be there, where GraphQL will ask Drupal if anything has changed while loading or after loading the specific page, if yes, the page will be reloaded. Another way is to actually have a web socket opened and Drupal pushes all resources directly in there.
Where is all the development on the Drupal GraphQL module taken? All the development, work and releases can be followed on: https://github.com/drupal-graphql/drupal-decoupled-app.