GraphQL for Drupalers - part 3 - the fields
GraphQL is becoming more and 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 series, we'll try to provide an overview of its features and see how they translate to Drupal.
In the last post we covered the basic building blocks of GraphQL queries. We started with the naming conventions, then we took a look at how and when to use fragments. Finally, we moved on to aliases, which can be used to change names of the fields as well as to use the same field more than once in the same block. This week we'll delve into the ambiguous concept of Fields.
What exactly are GraphQL fields?
Fields are the most important of any GraphQL query. In the following query nodeById, title, entityOwner, and name are all fields.
Each GraphQL field needs to have a type that is stored in the schema. This means that it has to be known up front and cannot be dynamic. At the highest level, there are two types of values a field can return: a scalar and an object.
Scalar fields are leafs of any GraphQL query. They have no subfields and they return a concrete value, title and name in the above query are scalars. There are a few core scalar types in GraphQL, e.g.:
String: A UTF‐8 character sequence.
Int: A signed 32‐bit integer.
Float: A signed double-precision floating-point value.
Boolean: true or false.
Objects, like nodeById and entityOwner in the query above, are collections of fields. Each field that is not a scalar has to have at least one sub-field specified. The list of available sub-fields is defined by the object's type. If we paste the query above into graphiQL (/graphql/explorer), we'll see that the entityOwner field is of type User and name is one of User's subfields (of type String).
Fields can also have arguments. Each argument has a name and a type. In the example above nodeById field takes two arguments:
id (String) and
langcode. The same field can be requested more than once with a different set of arguments by using aliases, as we've seen in the last post.
How do Drupal fields become GraphQL fields?
One of the great new traits of Drupal 8 core is the typed data system. In fact, this is the feature that makes it possible for GraphQL to expose Drupal structures in a generic way. For the sake of improving the developer experience, especially the experience of the developers of decoupled frontends, Drupal fields have been divided into two groups.
The first group comprises all the field types that have more than one property. These fields are objects with all their properties as sub-fields.
This is how we'd retrieve values of a formatted text field (body) and a link field. Date fields and entity references also fall into this category. The latter have some unique features so let's check them out.
Entity reference fields
This type of field has 2 properties: the scalar target_id and the computed entity. This special property inherits its type from the entity that the field is pointing to. Actually, we've already seen that in the named fragments example in the last post, where fieldTags and fieldCategory were both term reference fields. Let's bring a simplified example.
Since fieldCategory links to terms, its entity property is of type TaxonomyTerm. We can go further.
The entityOwner property is of type User, so we get their email. Apparently, we can go as deep as the entity graph is. The following query is perfectly valid too.
It retrieves the title of an article that is related to the article that is related to the article with node id one and this is where GraphQL really shines. The query is relatively simple to read, it returns a simple-to-parse response and does it all in one request. Isn't it just beautiful? :)
The second group comprises all the field types that have exactly one property (usually called value), like core plain text fields, email, phone, booleans and numbers. There's been a discussion about whether such fields should be rolled up to scalars or remain single-property objects. The former option won and in 3.x members of this group have no sub-fields.
That's it for the fields. Next week we're going to talk about... fields again :) but this time we'll see how to create one.