What is the problem to solve?

Drupal Core's JSON:API module and the related JSON:API module ecosystem has experienced strong adoption among those building decoupled Drupal sites. There has also been substantial growth in JavaScript community projects that depend on Drupal's JSON:API implementation. While those projects differ in a variety of ways, they all share at least one common need - easily interfacing with Drupal's JSON:API endpoints. This has resulted in many different implementations solving this need with large amounts of overlap, and very few shared solutions.

A non-exhaustive list of projects that include some form of client-like functionality for interacting with JSON:API includes:
- Druxt - https://www.npmjs.com/package/druxt
- Next For Drupal - https://github.com/chapter-three/next-drupal
- Drupal State - https://www.npmjs.com/package/@gdwc/drupal-state
- Drupal JS SDK has https://www.npmjs.com/package/drupal-js-sdk
- https://www.npmjs.com/package/nuxtjs-drupal-ce
- https://github.com/jsdrupal/js-client
- https://gitlab.com/VoidE/drupal-sdk
- Almost certainly more - please add your project in the comments :)

And this list doesn't even include specific decoupled site builds, many of which have at least some custom code to interact with JSON:API.

There have been previous attempts to solve this problem, and semi-recent discussions about renewing efforts to address this (much of this proposal is inspired by previous discussions with @deciphered.) I believe it is time to make new concrete steps to solve this problem.

Who is this for?

There are two primary audiences:
1. JavaScript developers who are consuming Drupal's JSON:API endpoints and would prefer to use a sanctioned Drupal solution to make this process easier. Of specific note within this audience are JavaScript developers who may not have deep existing experience with Drupal or the JSON:API spec.
2. Project maintainers within the Decoupled Drupal ecosystem who would prefer to spend less time re-solving common problems and more time pushing Decoupled Drupal forward.

The Result

Assemble a team of interested contributors who commit to developing a JSON:API client will be published under the @drupal namespace on NPM. This project will be able to be used as a dependency both for specific decoupled builds, and other decoupled ecosystem projects that interface with Drupal's JSON:API.

How will we know the desired result is achieved?

Downloads of this package reported on NPM would be a metric that indicates adoption. Strong adoption would also hopefully result in this package being listed high in the results when searching for Drupal on NPM. If this project is successful, there should be a reduction in projects that develop bespoke solutions to communicate with JSON:API, although this will likely be a more difficult metric to measure.

Why Now

I believe there are a number of reasons that make now the right time to renew these efforts.

- Accelerating innovation in the Decoupled Drupal JS ecosystem - If this effort can provide a desirable solution for interfacing with JSON:API, developers can focus more time and effort on the things that make their particular project unique.
- Prior art - reaching consensus on the functionality and format for this client will be difficult, but common patterns in projects that implement client-like solutions should help support decision making.
- Developing a repeatable pattern for 'official' JavaScript projects maintained by the Drupal community. The decoupled menus initiative and specifically the creation of the general project type has has an important impact on the the ability to create Drupal-adjacent community projects, but the path to any of these becoming 'official' Drupal projects (think more core, less contrib) still feels undefined. Most projects that fit this classification are either used by, or directly related to Drupal Core. A clearer path here could inspire more formal community efforts. Imagine an official collection of React utilities, or an official GraphQL client, etc.
- Sending a strong signal to the JS community - I continue to worry that Drupal has a perception problem with the JS community at large. While it is clearly not the only indicator, I think that searches on NPM tell a story here. Searching for Drupal results in a somewhat confusing set of packages, and it is unclear what if any are provided by the Drupal project. Those who know to look for the Drupal organization will only see two narrowly focused packages. A search for WordPress results in a client, and many packages under the @wordpress namespace. I'd imagine much of this is driven by the block editor, but it still could provide the perception that WordPress is serious about JS. Searching for Contentful provides a clear set of utilities, including packages to help consume data from Contentful. Contentful may not be a fair comparison here, since it is a completely headless CMS, but that doesn't change the fact that JS developers familiar with Contentful may have the expectation that any CMS they work with should have an official set of packages for them to take advantage of. I believe that offering more packages under the Drupal NPM namespace will help provide the signal that Drupal is JavaScript friendly.

Thoughts on potential approach

Determining the approach would primarily be the responsibility of the initiative if this moves forward, but here are a few concepts that I consider important:

- This package should be framework agnostic so that it can be used with any JavaScript framework or none at all.
- It should be possible to use both on the client and server.
- It should make underlying utilities available so that they can be adopted individually or incrementally without requiring the entire client.
- The client should provide a default solution for fetch, but it should be possible to provide a compatible alternative.
- The client should provide a default solution for storage / state management, but it should be possible to provide a compatible alternative.
- The client should be written in TypeScript, but it should be possible to use the client without using TypeScript.

Comments

brianperry created an issue.

Deciphered’s picture

> The client should provide a default solution for storage / state management, but it should be possible to provide a compatible alternative.

I don't know if this is viable. State management is usually dependent on the framework itself, e.g. Nuxt uses Vuex.
May be better to just provide multiple packges:
- @drupal/client
- @drupal/vuex
- @drupal/redux

And ideally, the project would be setup as a monorepo.

bbrala’s picture

I do think it makes sense to also have a client for Drupal. Although personally I do think facilitating connection to existing packages is quite helpfull. For example getting integration with Orbit.js working as it should would be great.

But again, as we talked about on DrupalCon, I agree on the value of a namespaced client and perhaps more packages. If we want to allow Drupal to be part of the js ecosystem we need to profile ourselves there. And connecting is hard at the moment, something a lot of people are running into right now when getting started with decoupled drupal.

Deciphered’s picture

> For example getting integration with Orbit.js working as it should would be great.

I believe it's important to keep the @drupal/client as technology agnostic as possible. A "@drupal/orbit" (or similar) would be an extension of the "@drupal/client" library. Otherwise the community is backing one technology over another, supporting one framework over another, which makes it an exclusive community instead of an inclusive community.

brianperry’s picture

Been a while and not a ton of activity on this issue. Not sure if that is a side effect of not really being able to push this, or an indication of a lack of interest.

I still think this is an important effort for Drupal, but I also think my thoughts on the approach here have evolved. While a client would still be a desirable long term outcome from this work, I think there would be substantial value in first focusing on the underlying utilities that a client would depend on - fetch, common JSON:API operations, etc. It should be able to make meaningful progress on these narrowly scoped utilities quickly. Ideally, existing clients could begin to adopt these utilities. Over time, we'd have what we need to create our own client based on these utilities if desirable, and these utility methods will have been exercised by existing projects.

The DrupalCon Europe keynote closed with some calls to continue to invest in headless after Drupal 10 is released, and even posed the question of if there should be an official core reference JS application. This work could be a foundation to that effort, and it feels to me like the time to start is now :)

TheodorosPloumis’s picture

I do agree with this proposal. An "official" JS SDK would be so helpful for the developers. Beside that, it would help in the promotion of Drupal itself as a Decoupled Backend solution.

On the following repository we are trying to collect all the JS stuff related with Drupal: https://github.com/eworx-org/drupal-js. It is not complete but has a lot of data available already.