Defining custom GraphQL types and resolversfor Drupal 8 , 9 , 10 , and 11

Last updated :  

In our journey with headless Drupal, we’ve previously explored customizing JSON:API endpoints using jsonapi_extras. Today, we'll expand our toolkit by delving into GraphQL, focusing on defining custom types and resolvers. This will allow you to enrich the granularity and efficiency of data queries in your application.

Introduction to GraphQL in Drupal

GraphQL is a powerful query language for APIs, enabling clients to request exactly the data they need. The flexibility of GraphQL makes it an ideal choice for headless applications, facilitating complex queries with a simple syntax. In Drupal, you can further enhance this by defining custom GraphQL types and resolvers.

Installing and Setting Up GraphQL Module

First, ensure that the GraphQL module is installed and enabled in your Drupal site:

    composer require drupal/graphql
    drush en graphql -y
    

This module provides the GraphQL API and data modeling capabilities out of the box.

Defining Custom GraphQL Types

Step 1: Conceptualize Your Custom Type

Consider a scenario where you need a custom type named CustomArticle, which contrasts with standard content by incorporating fields such as a summary and a publication date.

Step 2: Creating the GraphQL Schema

Create a schema file within the modules/custom/your_module/graphql/ directory with the .graphqls extension, e.g., custom_article.graphqls:

    type CustomArticle {
      id: ID!
      title: String
      body: String
      summary: String
      publicationDate: String
    }

    type Query {
      customArticle(id: ID!): CustomArticle
    }
    

Define your queries and their types, ensuring each field type is specified appropriately within the schema.

Defining Custom Resolvers

Step 1: Implement Resolver Functions

Resolvers are functions that resolve data requests. Create a resolver file in modules/custom/your_module/src/Plugin/GraphQL/Schema/CustomArticleResolver.php:

    namespace Drupal\your_module\Plugin\GraphQL\Schema;

    use Drupal\graphql\GraphQL\Execution\FieldContext;
    use Drupal\graphql\GraphQL\Execution\QueryResult;
    use Youshido\GraphQL\Execution\ResolveInfo;

    class CustomArticleResolver {
      public function resolve($value, array $args, ResolveInfo $info, FieldContext $context) {
        // Fetch data from a Drupal node or a custom database query.
        $node = \Drupal\node\Entity\Node::load($args['id']);
        if ($node) {
          return new QueryResult([
            'id' => $node->id(),
            'title' => $node->getTitle(),
            'body' => $node->body->value,
            'summary' => $node->get('field_summary')->value,
            'publicationDate' => $node->getCreatedTime(),
          ]);
        }
        return NULL;
      }
    }
    

Step 2: Register the Resolver

Register the resolver to connect it with the schema by updating your module’s your_module.services.yml:

    services:
      your_module.graphql.custom_article_resolver:
        class: Drupal\your_module\Plugin\GraphQL\Schema\CustomArticleResolver
        tags:
          - { name: graphql_resolver, id: "Query.customArticle" }
    

Testing Your GraphQL Implementation

With your types and resolvers defined and configured, you can test your GraphQL endpoint using a GraphQL client such as GraphiQL:

    query {
      customArticle(id: "1") {
        id
        title
        summary
        publicationDate
      }
    }
    

This query will return the information for the specified CustomArticle, verifying the functionality of your custom definitions.

Conclusion

By creating custom GraphQL types and resolvers in Drupal, you enhance the expressive power of your API, allowing for precise and efficient data querying. This capability ensures that your headless Drupal application can meet the specific data demands of your front-end applications.

Teaser for Next Lesson

In our next lesson, we will delve into proxying external APIs through Drupal. This will open up new possibilities, allowing you to seamlessly integrate and consume external data within your application architecture. Stay tuned!