Supporting cross-bundle entity collections in JSON:API
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.
The current entity type and bundle route pattern gives us the following routes:
There is no single route to get all nodes or products regardless of their bundle:
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.
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.