Building module-specific REST or GraphQL endpointsfor Drupal 8 , 9 , 10 , and 11

Last updated :  

In our previous lesson, we focused on solving authentication issues related to OAuth and JWT in your Drupal application. Building on that knowledge, today we will discuss creating module-specific REST or GraphQL endpoints to provide custom data services for your headless Drupal site.

Understanding Module-Specific Endpoints

Module-specific endpoints are custom API entry points you create within a Drupal module. These endpoints allow you to serve data tailored exactly to your application's needs, whether you are building a REST or GraphQL endpoint.

Creating a REST Endpoint

Step 1: Define a Custom Module

First, you need a custom module where you’ll define your endpoint. Assume you have a module named custom_api. If not, create it by adding the following structure:

    /modules/custom/custom_api
    ├── custom_api.info.yml
    └── custom_api.module
    

In custom_api.info.yml, include the following:

    name: 'Custom API'
    type: module
    description: 'Provides custom API endpoints.'
    core_version_requirement: ^8 || ^9
    package: Custom
    

Step 2: Define the REST Resource

Create a src/Plugin/rest/resource/CustomEndpoint.php within your module directory. Here’s a basic template:

    namespace Drupal\custom_api\Plugin\rest\resource;

    use Drupal\rest\ResourceResponse;
    use Drupal\rest\Plugin\ResourceBase;
    use Symfony\Component\DependencyInjection\ContainerInterface;
    use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;

    /**
     * Provides a Custom REST Resource.
     *
     * @RestResource(
     *   id = "custom_rest_endpoint",
     *   label = @Translation("Custom REST Endpoint"),
     *   uri_paths = {
     *     "canonical" = "/api/custom-data"
     *   }
     * )
     */
    class CustomEndpoint extends ResourceBase {
      public function get() {
        // Custom logic to fetch data
        $data = ['message' => 'Hello, this is custom data'];

        // Return the response as JSON
        return new ResourceResponse($data, 200);
      }
    }
    

Step 3: Enable the REST Resource

Before utilizing the resource, ensure it’s enabled via the REST UI. Navigate to Admin > Configuration > Web services > REST and enable your custom_rest_endpoint.

Creating a GraphQL Endpoint

Step 1: Define a GraphQL Schema

In your module, create a GraphQL schema file graphql/custom.graphqls. For example:

    type Query {
      customMessage: String
    }
    

Step 2: Setup Resolvers

Create a resolver class to handle data retrieval:

    namespace Drupal\custom_api\GraphQL\Plugin\GraphQL\Schema;

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

    class CustomMessageResolver {
      public function resolve($value, array $args, ResolveInfo $info, FieldContext $context) {
        return new QueryResult('Hello, this is custom data from GraphQL');
      }
    }
    

Step 3: Bind Resolver to Schema

Edit your module’s service file custom_api.services.yml to connect the resolver:

    services:
      custom_api.graphql.query.custom_message:
        class: Drupal\custom_api\GraphQL\Plugin\GraphQL\Schema\CustomMessageResolver
        tags:
          - { name: graphql_resolver, id: "Query.customMessage" }
    

Conclusion

Congratulations on building custom REST and GraphQL endpoints tailored for your module in a headless Drupal application. These endpoints will help you deliver specific data in an efficient manner, centralizing your custom data operations.

Teaser for Next Lesson

Up next, we'll dive into using jsonapi_extras for creating custom fields. This addition will allow you to extend JSON:API capabilities, tailoring data output even further. Stay tuned!