Close

Contact us

Call Us on 1300 727 952
Find us

First Floor, 159 Victoria Pde
Collingwood, VIC 3066
(Google Map)

1300 727 952 
or
+61 3 9910 4099

 

Contact us

Close

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.

Roman B 18 April 2018

DrupalCon Baltimore

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.

Amazee Labs

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:

  • Performance
  • Accessibility
  • 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:

  • Frontend

    • React
    • Apollo
    • Redux
  • Backend

    • Drupal 8

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

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.

GraphiQL

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.

Frontend

  • React: frontend library by Facebook that’s quite widely used.

  • Apollo: a project of the GraphQL community that makes the GraphQL client. It contains a set of libraries/tools that enables you to use GraphQL in almost every language. There’s a GraphQL for React, a GraphQL for regular JavaScript, a GraphQL for PHP, a GraphQL for Python, etc. So it’s all about how you communicate to a GraphQL endpoint. There’s a GraphQL server implementation as well in case you want to write your own GraphQL client. More information can be obtained from the Apollo website.

  • 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 accessibility

Going back a couple of years ago, Amazee Labs was a big opponent of decoupled Drupal due to the underlying problems with search engine optimisation (SEO) and accessibility. Decoupled applications would send a very basic HTML to the browser and include a JavaScript file that loads the site components. The devices and engines that cannot run JavaScript (screen readers, web crawlers, etc.) would not be able to load the site and hence faced big SEO and accessibility problems.

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.

Isomorphic JavaScript

The browser requests the first page. If not cached already, the request is forwarded to a Nodejs server that has the code that you run in the browser also running locally. The server pre-renders everything (including the results of API requests to Drupal) and returns the result to the browser for display. This means that even if the device cannot run JavaScript, the site would still be functioning. In the HTML response, there is a little piece of JavaScript included that gets executed by the browser in case JavaScript is supported. The JavaScript will then slowly take over the whole site, and every link will be replaced with a React link so the browser morphs into a full React/JS application. Any additional requests will go to the API directly instead of talking to the nodejs server. The React application queries GraphQL directly and renders it. As Apollo (GraphQL Client) is using Redux as predictable state container along with the caching, all different requests are cached as different states of the React application which, in return, will give a very fast accessibility to all the different states/cached requests of the React application.

To try all this you can visit https://www.gaultmillau.ch. First, disable the JavaScript on your browser to actually see that everything is still pre-rendered and the browser still can display even if the JavaScript is disabled – Isomorphic JavaScript (nodejs server running and pre-rendering everything). Furthermore, going back to the home page and visiting different links, you will notice a fast response. All requests are cached after the first request and the browser easily displays the different responses (React application states).

Performance

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.

Hosting

Nodejs server needs to run in the hosting environment of Drupal as JavaScript files are requested to have some output.

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.

Conclusion

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.

Is the Nodejs server going to be removed in the future?Is it really needed? If you want to have server-side rendering, you will still need nodejs server in the Drupal GraphQL module. If that’s removed, you can have a hosting company that has Nodejs server, or you can bundle all your JavaScript instead and push it to the Drupal site to ensure it’s executed, as all Nodejs does is actually execute JavaScript.

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.

Contact us

Subscribe to the Salsa Newsletter

Subscribe to the Salsa newsletter

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×