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 GraphQL to assemble queries that are a bit more complex.
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.
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:
GraphQL Fragments, as the name implies, are just pieces of a query. They mostly serve two purposes:
- 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.
- 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.
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.