Part 1 | Part 2 | Part 3

For several years now, decoupled Drupal has been among the topics that has fixated members of the Drupal community. At present, there is no shortage of blog posts and tutorials about the subject, including my own articles, as well as a comprehensive book covering decoupled Drupal and an annual conference in New York City to boot. Now that JSON:API has been part of Drupal core for quite some time now, some of the former obstacles to implementations of decoupled Drupal architectures have been lowered.

However, though we have seen a large upswing in the number of decoupled Drupal projects now in the wild, some areas of the decoupled Drupal ecosystem have not yet seen the spotlight afforded projects like JSON:API and GraphQL. Nonetheless, many of these contributed projects are critical to adding to the possibilities of decoupled Drupal and can abbreviate the often lengthy period of time it takes to architect a decoupled Drupal build properly.

In April of last year, this author (Preston So, Editor in Chief at Tag1 Consulting and author of Decoupled Drupal in Practice) spoke to a packed auditorium at DrupalCon Amsterdam about some of the lesser-known portions of the decoupled Drupal landscape. In this multi-part blog series, we survey just a few of these intriguing projects that can serve to accelerate your decoupled Drupal implementations with little overhead but with outsized results. In this third and final installment, we cover several projects that encompass some of the most overlooked requirements in decoupled Drupal, namely JSON-RPC, Schemata, OpenAPI, and Contenta.js.

Running Drupal remotely with JSON-RPC

Just before we continue, it's important that you have exposure to the other information provided in this series for the most complete possible perspective on these projects that make decoupled Drupal even more compelling. This third and final installment in the blog series presumes knowledge already presented in the first and second installments, in particular the summary of motivations behind JSON-RPC provided in the installment immediately preceding this post.

Maintained by Mateu Aguiló Bosch (e0ipso) and Gabe Sullice (gabesullice), the mission of JSON-RPC is to serve as a canonical foundation for Drupal administrative actions that go well beyond the limitations and possibilities of RESTful API modules like core REST, Hypertext Application Language (HAL), and JSON:API. The JSON-RPC module also exposes certain internals of Drupal, including permissions and the list of enabled modules on a site.

To install JSON-RPC, use the following commands, which also enable JSON-RPC submodules.

    $ composer require drupal/jsonrpc
    $ drush en -y jsonrpc jsonrpc_core jsonrpc_discovery

Executing Drupal actions

To rebuild the cache registry, you can issue a POST request to the /jsonrpc endpoint with the following request body, and JSON-RPC will respond with the following response body and a 204 No Content response code.

    {
      "jsonrpc": "2.0",
      "method": "cache.rebuild",
    }

To retrieve a user's permissions, you can similarly issue a POST request to the same /jsonrpc endpoint, which will respond to your request with a 200 OK response code and a list of the user's permissions.

    {
  "jsonrpc": "2.0",
      "method": "user_permissions.list",
      "params": {
    "page": {
      "limit": 5,
          "offset": 0
        }
  },
      "id": 2
    }

All JSON-RPC methods

The table below shows some of the other common methods that you can execute by issuing requests to JSON-RPC. For a deeper explanation of JSON-RPC as well as a full account of what features JSON-RPC makes available to decoupled Drupal architectures, consult Chapter 23 of my book Decoupled Drupal in Practice.

drawing

Derived schemas and documentation with Schemata and OpenAPI

In API-first approaches, schemas are declarative descriptions that outline the shape of a JSON document, such as a typical entity response from a Drupal web service. In Drupal 8, the Schemata module, maintained by Adam Ross (grayside), is responsible for providing schemas that facilitate features that were previously impossible in Drupal such as generated API documentation and generated code, both of which we will examine shortly. To install the Schemata module, execute the following commands:

    $ composer require drupal/schemata
    $ drush en -y schemata schemata_json_schema

Navigating schemas

With Schemata, you can navigate a schema to learn more about how the API issues and handles data either by using the browser or by issuing GETrequests against endpoints that are prefixed with /schemata. Consider, for instance, the following format for Schemata requests:

    /schemata/{entity_type}/{bundle}?_format={output_format}&_describes={described_format}

Here are two examples of schema navigation with regard to the possible URLs against which you can issue requests. Note that in the first example, we are requesting a description of the resource according to the JSON:API module, whereas in the second we are requesting it in the HAL format found in Drupal 8's core REST module.

    /schemata/node/article?_format=schema_json&describes=api_json

    /schemata/user?_format=schema_json&describes=hal_json

In the image below, you can see the result of a sample response from Schemata for the schema describing article data.

Schemata sample response

OpenAPI

OpenAPI is a separate project, formerly known as the Swagger specification, which describes RESTful web services based on a schema. The OpenAPI module, maintained by Rich Gerdes (richgerdes) and Ted Bowman (tedbow), integrates with both core REST and JSON:API to document available entity routes in both web services modules.

The unique value proposition for OpenAPI for decoupled Drupal practitioners is that it offers a full explorer to traverse an API schema to understand what requests are possible and what responses are output when the API issues a response. To install OpenAPI, execute the following commands, depending on whether you prefer to use ReDoc or Swagger UI, both of which are libraries that integrate with OpenAPI to provide styles for API documentation.

    # Use ReDoc.
    $ composer require drupal/openapi
    $ composer require drupal/openapi_ui_redoc
    $ drush en -y openapi openapi_ui_redoc

    # Use Swagger UI.
    $ composer require drupal/openapi
    $ composer require drupal/openapi_ui_swagger
    $ drush en -y openapi openapi_ui_swagger

One of the more exciting use cases that OpenAPI makes possible is the idea of generated code, which is dependent on the notion that generated API documentation based on derived schemas means that APIs are predictable. This opens the door to possibilities such as generated CMS forms with built-in validation based on what these schemas provide. For more information about generated code based on the advantages of derived schemas and generated API documentation, consult Chapter 24 of my book Decoupled Drupal in Practice.

Revving up with proxies:

One final project that we would be remiss not to cover as part of this survey of hidden treasures of decoupled Drupal is Contenta.js, authored by Mateu Aguiló Bosch (e0ipso), which addresses the pressing need for a Node.js proxy that acts as middleware between a Drupal content API layer with web services and a JavaScript application. As many decoupled Drupal practitioners have seen in the wild, a Node.js proxy is often useful for decoupling Drupal due to its value in offloading responsibilities normally assigned to Drupal.

Contenta.js integrates seamlessly with any Contenta CMS installation that exposes APIs, as long as the URI of the site is provided in that site's configuration. Many developers working with decoupled Drupal are knowledgeable about Contenta CMS, an API-first distribution for Drupal that provides a content repository optimized for decoupled Drupal while still retaining many of the elements that make Drupal great such as the many contributed modules that add to Drupal's base functionality. (Another similar project, Reservoir, has since been deprecated.)

One of the compelling selling points of Contenta.js is that for Contenta installations that already have modules like JSON:API, JSON-RPC, Subrequests (covered in Chapter 23 of Decoupled Drupal in Practice), and OpenAPI need no further configuration in order for Contenta.js to work with little customization out of the box. Contenta.js contains a multithreaded Node.js server, a Subrequests server facilitating request aggregation, a Redis integration, and a more user-friendly approach to cross-origin resource sharing (CORS). For more information about Contenta.js, consult Chapter 16 of my book Decoupled Drupal in Practice.

Conclusion

Decoupled Drupal is no longer theoretical or experimental. For many developers the world over, it is now not only a reality but also a bare minimum requirement for many client projects. But fortunately for decoupled Drupal practitioners who may be skittish about the fast-changing world of API-first Drupal approaches, there is a rapidly expanding and maturing ecosystem for decoupled Drupal that furnishes solutions for a variety of use cases. Most of these are described at length in my book Decoupled Drupal in Practice.

In this final installment, we covered some of the major modules—and one Node.js project—that you should take into consideration when architecting and building your next decoupled Drupal project, including JSON-RPC, Schemata, OpenAPI, and Contenta.js. And in this multi-part blog series, we summarized some of the most important projects in the contributed Drupal landscape that can help elevate your decoupled Drupal implementations to a new level of success, thanks to the accelerating innovation occurring in the Drupal community.

Special thanks to Michael Meyers for his feedback during the writing process.

Part 1 | Part 2 | Part 3


Photo by ASA Arts & Photography on Unsplash