GraphQL for Drupalers - part 2 - the queries

GraphQL is becoming more popular every day. Now that we have a beta release of the GraphQL module (mainly sponsored and developed by Amazee Labs) it's easy to turn Drupal into a first-class GraphQL server. In this second post of the series, we'll describe they way Drupal fields are represented in GraphQL and look at a few examples.

GraphQl for Drupal

Last week we talked about the new structure of the GraphQL package. We have also looked at the tools bundled with the module - the explorer and the voyager - and we've explored how to fetch a username. Now let's use GraphiQL to assemble queries that are a bit more complex.

The Naming

GraphQL naming conventions are slightly different than Drupal's.

  • Fields and properties are in camelCase. This means that field_image in Drupal becomes fieldImage in GraphQL and the revision_log property becomes revisionLog.
  • Entity types and bundles use camelCase with the first letter capitalized so taxonomy_term becomes TaxonomyTerm and the tags vocabulary becomes TaxonomyTermTags. As we can see bundles are prefixed with the entity type name.

The structures

While fields and properties both translate to the same GraphQL structure called Field, entity types and bundles, despite sharing the naming convention, don't. The former is implemented as GraphQL Interfaces and the latter are GraphQL Types (implementing these Interfaces). As an example: 

This query contains fields from 3 different GraphQL structures that build upon one another.

  • entityId and entityCreated come from the Entity Interface. These fields are available for all entity objects. nodeById query returns a Node Interface which extends Entity Interface.
  • title and status are defined in the Node Interface and are available for all nodes, regardless of their content type.
  • fieldSubtitle is a field (field_subtitle in Drupal) that has been added to the Article content type. It's not a part of neither Node nor Entity Interfaces, it is only available in the NodeArticle Type. nodebyId can return any node, not just Article, so we need to wrap the fieldSubtitle in a GraphQL Fragment.

If we paste the query into GraphiQL (/graphql/explorer) we'll get a result similar to this one:

The Fragments

GraphQL Fragments, as the name implies, are just pieces of a query. They mostly serve two purposes:

  1. Executing part of a query conditionally - only when the result is of a specified type. In the example above fieldSubtitle will be evaluated only when the node with id 1 is an Article. If it turns out to be a Basic Page, the fragment will be omitted and the response will just be one field shorter without raising any exceptions.
  2. Reusability. A fragment can be given a name and be used more than once.

There are two fragments in this query. The first one starting on line 3 is an inline fragment. We need it because fieldCategory and fieldTags are only attached to Articles and nodeById can return any node.

The other one, defined on line 18, is a named fragment thanks to which we don't need to repeat the sub-queries for fieldCategory and fieldTags.

This is how the result could look like. Node 1 is an Article, it has 2 tags in one category term.

The Aliases

There might be situations when we want to use the same field more than once in a single query, to fetch node 1 and 2 simultaneously for instance. We can do that thanks to GraphQL Aliases

Here we're calling nodeById twice, each time with different arguments and aliases. The former will appear under nodeOne key in the result and the latter will be available under nodeTwo. We've also transformed the inline fragment holding the article fields into a named fragment and used it in both queries to reduce unnecessary repetition.

That's it for this post. In the next one, we'll see how to retrieve the values of Drupal fields and properties.

November 23, 2017

Get our Newsletter


How I can filter the results in a nodeQuery? Like I would in a normal View or the "where" clause in a SQL Statement. I notices that it receives a NodeQueryFilterInput but I don't see how to use it

By Daniel Noyola
3 months ago

Hi Daniel,

That's a good question. Actually, it might make sense to change the order of posts in the series a bit to cover this topic next - right after the recent one on fields:

To answer your question - right now there's no generic way of executing arbitrary SQL queries with core graphql. nodeQuery will let you filter by base fields. You can check the available options by clicking the NodeQueryFilterInput in the explorer. In order to run more complex queries you could try the graphql_views or write your own field plugin.



By Blazej Owczarczyk
3 months ago

Good run-down. Waiting for part 2!

By Hamza
3 months ago

Thanks a lot :). The next post is already online and hopefully more will come too.

By Błażej Owczarczyk
3 months ago

1 second ago

Add new comment

You must have Javascript enabled to use this form.
What is Amazee Labs?