Expanding JSON:API support in Drupal Commerce
Our vision is to power eCommerce innovation through every stage of growth. Most of our users start out running Drupal full-stack, responsible for both the front-end and the back-end. Many reach a point where growth demands decoupling the front-end to improve performance, create unique customer experiences, or both. If not that, most will need to expose Centarro Commerce data to the other business systems they implement to run their companies.
To facilitate these use cases, we’ve focused hard on designing and developing a JSON:API based Commerce API module, making it a core concern in our product roadmap. This module builds on our previous efforts, such as the Cart Flyout module that progressively decoupled the shopping cart.
When deciding on what we wanted an HTTP API to accomplish, we considered every aspect of our data model and how front-end applications need to interact with it, including:
- Retrieve a list of products while still supporting the Commerce framework's dynamic pricing capabilities, e.g. customer type or currency based price lists.
- Add a product to a cart without the API consumer having to understand how to determine the current store, whether or not to use an existing cart or creating a new cart, and how to turn that product into a cart order item.
- Manipulate a cart without requiring the API consumer to have full order management permissions. It should only be able to modify specific elements of a cart for the current customer (e.g. order item quantities) and not perform administrative tasks on the cart or manipulate other users' orders.
- Collect shipping and billing information to complete checkout and receive payment.
Standardizing on the JSON:API specification
In 2018 we released the Commerce Cart API module, which let you work with carts through an HTTP API using the RESTful Web Services module available in Drupal core. Building that module taught us some great lessons on what it would take to build a versatile HTTP API for Centarro Commerce.
For example, we found that working with the core RESTful Web Services module:
- Required us to define our own request and response schema for our data model.
- Required us to write custom data normalizers to handle how data object were represented, such as relationships and complex field values.
Leveraging JSON:API as implemented for Drupal allowed us to focus on figuring out the mechanics of how our API should interact with the Commerce data model – not how it should be entirely represented in JSON. Thankfully, the JSON:API module became a core part of Drupal in last year's 8.7 release. For some background on that process, Drupal project lead Dries Buytaert wrote an excellent overview of the JSON:API module's journey from contributed module to core.
Our Commerce API module extends the JSON:API module to create custom resource routes that we use to provide a Cart and Checkout API. Instead of having to invent ways to return data, we could focus our efforts on providing a more usable interface for Commerce developers, leaving the JSON:API module to handle the rest.
What’s in the current release and what’s next?
The initial release of Commerce API supports the complete customer journey from finding a product to adding it to a cart, applying a promotion code, and proceeding through checkout. It includes support for providing shipping information and selecting a shipping method. Payment for checkout currently relies on an off-site payment gateway, such as PayPal Checkout. The ability to use an on-site gateway like Braintree or Stripe is on the roadmap.
We also take advantage of the Entity API to handle billing and shipping information, which is actually stored in a variety of related entities. Billing information is stored on a profile entity and is referenced by an order or payment method. Shipping information is also stored on a profile entity and referenced by shipments. To simplify data entry, we added pseudo-properties to orders,
shipping_information, that will create or modify these profiles directly from an order API request without requiring API consumers to create the entities first and populate the references. This lets us provide a full representation of our data model without exposing its internal workings.
Our next steps for the Commerce API module are to ensure we have Wishlist support and work on handling on-site payment gateways.
Through our work on the Commerce API module, we're helping shape the public PHP API for extending the JSON:API specification in Drupal. Some components in the Commerce API are part of pending Drupal core issues that I hope to see land for 9.1.x, which will release later this year.
- Allowing the specification of meta information on resource objects and relationships
- Allow the aliasing of resource type names and their paths
Can I give it a try?
Of course! You can grab the Commerce API module and install it like any Drupal module. Be sure to check out the documentation.
Want to try out a demonstration? Check out this React demo: https://centarro-commerce-demo.web.app/.
In the future, we'll be releasing the sample React application on our GitHub.
Want to learn more?
Come see my sessions at the following events (and say Hi! 👋), and stop by the Centarro booth at DrupalCon!