Graphql Drupal 8

Drupal CMS Data with Custom GraphQL Schemas

The Drupal GraphQL module enables your Drupal website to create GraphQL schemas and expose Drupal entities with GraphQL client applications. Pathauto Module Having a well-structured URL does not only improve the user experience, it is very vital for search engine optimization too.

In this article I am going to setup a custom GraphQL schema that Drupal can use to export CMS data. This article will show how to extend the Drupal 8 GraphQL module and use its examples to build a real world example of a GraphQL server in Drupal 8 while exposing only the data we need in a meaningful way to our front end users.

Prerequisites

  1. Installing GraphQL for Drupal 8 The Drupal GraphQL module supports all the GraphQL specifications and can be used to build and expose GraphQL schemas. The latest alpha release of the Drupal 8 module in the version 8.x-4 offers a capability for Drupal modules to extend the schema with a plugin.
  2. Course Web Services in Drupal 8; GraphQL with Drupal: Getting Started; React + Drupal. Whether you’re enhancing a few of the elements on an existing page, or creating a fully decoupled single-page app (SPA), React and Drupal work great together.

I am going to assume that you have a Drupal environment available with the Drupal 8 GraphQL module installed. We will also need access to edit module files.To quickly get up and running with Drupal 8 and GraphQL check out these other articles:

Additionally, it will be helpful to clone the example Drupal module I’ll use later in the article for examples. See the Github project here: https://github.com/motobreath/drupal-graphql.

Seed Data

I’ll create a new content type called Product. Along with the default body field, we’ll add an image field with a machine name field_product_image and a decimal field price with a machine name of field_price.

And then add content:

With our product content created we can expose our product data as GraphQL. To do this we’ll need to do a few things: create our GraphQL schema, expose the Drupal data, and create our GraphQL server. First off lets define our schema.

Extend Drupal 8 GraphQL Module

According to the official documentation for the GraphQL module,we should copy the examples directory into our own custom module to extend the examples. At first I thought to myself “why not just modify the examples”?After playing with the schemas, and promptly breaking the code, I found copying the examples out to my own module is a huge help.

I’ve cloned the repo and created a new Drupal module called my_graphql. You can clone the code from my Github repo here, if you haven’t already: https://github.com/motobreath/drupal-graphql.

GraphQL Schema

Creating your schema includes exposing the data that is relevant to your consumers and nothing else. In the my_graphql module, the graphql folder contains the following files:

  • products_extension.base.graphqls
  • products_extension.extension.graphqls
  • products.graphqls

The products.graphqls file is where we define our product data. You’ll see in this file I’ve defined a Product type with id, title, image, and price fields:

The other two extension files are used to define what queries and pages look like in GraphQL, for these I’ve only changed the example names to match my product content type names.

Expose Product Data

Now we need to let Drupal know how to expose our product data. We can do this by using the Schema plugin provided by the GraphQL module. In the folder my_graphql/src/Plugin/GraphQL/Schema folder, you’ll see my ProductsSchema.php file, and in there the addProductFields method where I use the ResolverRegistry and ResolverBuilder objects to pull my product content data from Drupal.

For my schema I am proving id, title, price, and image:

The Drupal 8 GraphQL module provides many more ways to pull your Drupal data, see the documentation on resolvers for more information: https://drupal-graphql.gitbook.io/graphql/v/8.x-4.x/data-producers/built-in.

Data Producer

We also need to define a data producer for Drupal. This file is defined in my_graphql/src/Plugin/GraphQL/DataProducer in the file QueryProducts.php. The class QueryProducts extends the Drupal 8 GraphQL DataProducerPluginBase class and essentially wires up the GraphQL queries to the schema we provided earlier. The example class QueryArticles has the necissary methods already defined, so I just changed the class to use my products schema instead of articles.

Create GraphQL Endpoint

Graphql

With our schema and data producers in place for our product data we can create the GraphQL server. We can do this in the admin UI, visit Configuration -> Graph QL or the url /admin/config/graphql and click the +Create Server button:

For the server details:

  • Label of Products
  • select Products schema for the Schema
  • Endpoint will be /graphql/products
  • Uncheck Allow query batching
  • Uncheck Enable caching
  • Check Enable debugging

Drupal 8 Graphql Views

Save your changes when done. When back on the server screen you will see your new Products server, with an Edit button under Operations. Click the down arrow next to Edit to see more options including Explorer and Voyager. Select Explorer to bring up the GraphQL query explorer.

GraphQL Query

We can now query our products! To return all products with a count, use the following query, and click the play button:

If you set up your Drupal content similar to mine, you should see the data returned:

You can use the query explorer to help write your GraphQL queries. The Documentation Explorer can also help define what queries you can write, based on your schema.

Conclusion

Having our Drupal data exposed as meaningful GraphQL for end users to consume is a huge advantage. In previous versions of the Drupal 8 GraphQL module you could only expose the data in Drupal terms, for example field_price but if our consumers weren’t familiar with this nomenclature, the GraphQL would be overcomplicated and unusable.

Sources

Drupal 8 GraphQL in Action

In this article we are going to put to use the Drupal 8 GraphQL module by exposing endpoints that run custom GraphQL queries. With these custom queries we can get the data back from Drupal that we need, without confusing our end users with all of the Drupal fluff.

Prerequisites

You should have Drupal 8 installed with the GraphQL module enabled. Also, while we won’t be talking specifically about the files included with this module, it is always helpful to have access to the PHP files that come with the GraphQL module so ensure you are able to edit the module files in your local IDE. If you need help with setting up any of your workspaces, here are some resource:

Installing GraphQL on local environment:

Local development using Drupal and Docker:

Both of these articles are good starting points to working with GraphQL and Drupal.

Examples Module:

When enabling the GraphQL module, ensure that you have the examples module enabled as well. We will use the examples to configure our GraphQL endpoint next. If you havent already, enable it from the Extend menu.

If you have your local environment ready, Let’s get started!

Viewing the GraphQL

Visit Configuration -> Graph QL or the url /admin/config/graphql and click the +Create Server button.

I set the following options on the page:

  • Articles for the Label
  • Example Schema for the Schema
  • /examples/article for the Endpoint
  • Allow query batching checked
  • Enable caching checked
  • Enable debugging checked (Because what could be wrong with more debugging?)

Save the server, and then in your browser use the url /graphql/examples, you’ll see this wonderful output:

At first you see the error page, and you think its all broken! But it’s working as expected, we are seeing GraphQL being output to the browser. This is a great start! Now lets look into how to write queries.

Content for GraphQL Query

First we need content to query against. In a nutshell I quickly created a few pages of content using the Article content type, which is out of the box Drupal to simplyfy things. Here is a quick example of content, a few articles:

Once your content is created, now you can query that data using GraphQL queries. But how do I write a GraphQL query string?

Using GraphiQL

GraphiQL is a GUI for managing GraphQL queries. From their GitHub Account:

GraphiQL is the reference implementation of GraphQL IDE, an official project under the GraphQL Foundation.

To get to the GUI, you can select Edit -> Explorer from the GraphQL module page, or you can browse directly to the GraphIQL for your specific server at:

/admin/config/graphql/servers/manage/{graphql_server}/explorer

Where you replace {graphql_server} with the name of your server, in our case articles:

/admin/config/graphql/servers/manage/articles/explorer

Graphql Drupal 8 Tutorial

Once we have our GUI to test our GraphQL queries, we can write queries to pull our desired data.

Note:At first writing GraphQL syntax was a little cumbersome for me. I started by reading the GraphQL documentation and playing with the GraphiQL editor, and then it started to click. Then I found this great article from Amazee Labs on how to work with GraphQL in the Drupal world. In the end I found that I could write SQL, then GraphQL would fall right in line.

Pro Tip:VS Code also has a GraphQL plugin so you can get syntax highlighting in your editor!

The GraphSQL Query

After playing the GraphiQL query editor I was able to come up with this query, where id:3 is the ID of my article:

And running it through the GraphiQL this result:

We can now see the JSON that is available to end users through the GraphQL endpoints. So how do those users get their data?

GraphQL Request

Requests to get data from our Drupal GraphQL server must use HTTP POST to query data. This is because of our need to send the actual graph query in correct syntax. To make a POST request I use Postman 7.3.5 which now has a GraphQL query window that you can send as your POST request. Note: This can be done with previous versions of Postman, or with any http client, you would send your GraphQL query as a string.

I send the POSt request with the following configuration:

  • Method: POST
  • URL: http://localhost:8099/examples/article
  • Body: raw

And the payload to send:

Conclusion

We should now have a Drupal instance up that can return articles via GraphQL queries, either by the built in explorer, or over HTTP via Postman or similar clients. At this point we can add more GraphQL schemas to Drupal to return more data and extend our Drupal CMS to third party applications like front end applications like ReachJS, or expose our GraphQL to other back end systems to stich together meaningful data.