Supporting cross-bundle entity collections in JSON:API

Developer Desk

Last week I recapped my experience at Decoupled Days 2019, and there's one exciting development coming out of that event I wanted to write more about. We've had a serious challenge using the JSON:API module with Drupal Commerce for a while now – cross-bundle entity collections.

Drupal Commerce lets merchants define any number of product types to match their product data models. However, these different types of products all need to be represented in a single product catalog. Building that is easy enough with Drupal's Views module, but it's a challenge via JSON:API given it's oriented more toward serving entities of a single type, or bundle, from its collection resources.

There's an issue from 2018 to discuss cross-bundle entity collections for JSON:API. The current JSON:API implementation takes creates a series of routes based on each entity type and its bundles. This was a blocker for us, and it was also discovered to be problematic for the JavaScript Modernisation & Admin UI initiative (for the /admin/content interface).

The current entity type and bundle route pattern gives us the following routes:

  • /jsonapi/node/articles
  • /jsonapi/node/pages
  • /jsonapi/commerce_product/clothing
  • /jsonapi/commerce_product/books

There is no single route to get all nodes or products regardless of their bundle:

  • /jsonapi/node
  • /jsonapi/commerce_product

The current approach reflects trade-offs in prior planning and decision-making led by Mateu Aguiló's. The JSON:API module needed to be particular in some implementation, and this also led to healthy discussion and design around each change. The Admin UI team created an internal jsonapi_support to iterate on this design, but it quickly fell behind the JSON:API module's development as the maintainers prepared for its move into Drupal core for the 8.7 release.

For my Delivering Headless Commerce demonstration, I converted my React + GraphQL frontend to React + JSON:API with Drupal 8.7. To recreate our catalogs, I needed to be able to query for products of any type based on taxonomy term names. I took the work done by the JavaScript Modernisation team and ported it for JSON:API in Drupal core. It worked! 🎉


At the conference, I had the pleasure of sitting down with Mateu, Wim Leers, and Gabe Sullice to discuss the cross-bundle feature. We made a plan! We initially were not sure where the code should live. Should it go into JSON:API immediately, JSON:API Extras, its own contributed module? 

Our decision is to work in a separate contributed module for now. This affords users a more controlled opt-in experience and does not require users to install JSON:API Extras. It also provides a faster, leaner way to work solely on this feature. Ideally, the feature could move into the core JSON:API module once it matures.

We got a quick start in the new project, JSON:API Cross Bundles. Next steps include writing tests and discussing edge cases – particularly around filtering and field access. From our preliminary discussions, filtering on the root entity type collection will follow the same patterns as an entity query and inherit its behavior. For example, if there is a field only on one of the entity type's bundles, any other bundle is automatically excluded.

I would appreciate anyone needing this feature to help by documenting their use cases in this issue. Your requirements help us know more about why this feature is required beyond "because I need it," helping us design a more useful API for everyone.


Submitted by whatever (not verified) on Mon, 08/12/2019 - 18:02

congrats on such a nice article. Looking forward to a an awesome decoupled shopping experience with drupal :)

Add new comment