API extensibility overview

Overview of the concepts related to extending the functionality of your Composable Commerce Project.

Ask about this Page
Copy for LLM
View as Markdown

commercetools Composable Commerce provides out-of-the-box data structures and behavior that covers the needs of modern commerce solutions. However, your Project may have unique requirements which require these data structures and behavior to be extended.

Composable Commerce provides a range of API extensibility options, allowing you to customize your Project to accommodate various use cases and to enable further integrations. These customization options are Types, Custom Fields, Custom Objects, API Extensions, Subscriptions, and States.
Learn more about how to use API extensibility options with Composable Commerce in our self-paced Extensibility module.

We've collected a number of common use cases and the recommended extensibility options you can use to achieve them.

Extend resources with custom fields

Types are similar to Attributes defined by Product Types. They allow you to define extra fields on supported data types within Composable Commerce. For example, to keep track of loyalty information for a Customer, you could create a Type that defines a field for loyaltyPoints.

When you create a Type on a supported data type, the new fields are not automatically attached to all instances of that data type. Instead, you're creating the possibility to define those values when it makes sense to you. To define the values, you use Custom Fields.

Custom Fields refer to the values set for Types on a resource. To reference our earlier example, when creating or updating a Customer, you could use Custom Fields to define values for the newly created loyaltyPoints field.

Extend Project with custom resources

Custom Objects allow you to store namespaced JSON values within your Composable Commerce Project. Any number, string, boolean, array, object, or common API data type value can be saved. This allows you to store and update values used by integrations or other services which interact with your Project.

For example, if you needed to keep information about your individual retail stores, you could create a Custom Object for that use case. Within the Custom Object, you could define the store location, contact details, and any other store-specific information.

Extend API calls

API Extensions are called after the processing of a create or update request of an API call, but before the result is persisted. This makes it useful for synchronous tasks which must be performed before a resource is created or updated.

Good use cases for API Extensions are calculating custom shipping costs or adding mandatory items, like insurance, to a Cart.

API Extension within the flow of the API call

The API Extensions are called during the execution of a create or update request. The system first validates that the requested operation can be done, and applies the operation. However, the created or updated resource is not persisted yet. It is forwarded to the API Extensions, which can run their business logic on it. You can restrict this step to certain use cases with conditional triggers. An API Extension can respond in one of three ways:
  • If the Extension finds the result to be valid, and does not want to perform any changes, it can return a success. The system will persist the result.
  • If the Extension finds that the result is not valid (for example the particular Customer may not purchase this Product), it can return a list of errors. The system will not persist the result and return the errors to the original API Client.
  • If the Extension wants to perform additional changes, it can return a list of update actions (for example if it wants to add mandatory insurance to the Cart, it can return an AddLineItem update). The system will validate that the update actions are valid for the given resource type and will try to perform the updates. Should that fail, the original API Client will receive the errors. Otherwise, the original API Client will receive the final result (for example the Cart including the mandatory insurance).

If an API Extension fails to respond properly

If an API Extension fails to respond properly, the whole API call will fail. If the API Extension did not return a result in time or could not be reached, the original API Client will receive a 504 Gateway Timeout HTTP status code. If the API Extension returns a response, but it could not be parsed properly, the original API Client will receive a 502 Bad Gateway HTTP status code.

In both cases, additional information on the cause of the failure is returned to the original API Client.

In terms of Service Level Agreement (SLA), a failure caused by an API Extension does not count as a failure of the commercetools Composable Commerce API. For example, if an API Extension for the Carts is down and causes downtime for your shop, the SLA won't cover that.

Multiple API Extensions in a single API call

If multiple API Extensions are triggered by an API call, they will be called in parallel. Their responses will be merged, but without a guaranteed order (for example, if two Extensions each return an error, their order in the error list is undefined. If two Extensions return updates, the order in which the updates are performed is undefined).

Responses are merged based on their priority or severity:

  • A failure to respond properly by any API Extension will cause the whole request to fail with a 502 or 504.
  • Otherwise, if any API Extension finds that the result is not valid, the result will not be persisted and an error will be returned to the original API Client.
  • Otherwise, if any API Extension returns updates, the result will be modified before it is returned to the original API Client.

API Extensions should operate on separate concerns. For example for a Cart, it is fine to have an Extension each for validating that a Customer is allowed to purchase age-restricted Products, calculating shipping costs, and adding mandatory insurance. A counter-example is two API Extensions changing the Price of a Line Item: One for adding extra costs for optional gift wrapping, the other reducing the Price if an externally defined Discount applies - If both Extensions want to change the same Line Item, one will overwrite the result of the other. For this use case, the whole Price calculation for Line Items should be performed inside a single Extension.

You also need to find a balance between clean separation and the increasing latency risk when calling many parallel Extensions.

Reference Expansion in API Extensions BETA

By default, the payload sent to an API Extension contains only references to related objects, not the full objects themselves. If your business logic requires data from related objects, you can configure expansion paths on an API Extension. The payload then includes the expanded referenced objects, so you don't need to make additional API requests to retrieve them.
For example, if a Cart Extension needs to validate the Customer Group of the Customer on a Cart, you can configure the expansion path customerGroup. The Extension payload then contains the full Customer Group object, not just its reference.
You can configure up to 3 expansion paths per API Extension. To configure expansion paths when creating an API Extension, set the expansionPaths field in the ExtensionDraft. To update the expansion paths on an existing API Extension, use the Set Expansion Paths update action.
Be aware of the limits of this feature and its performance impact. Using Reference Expansion with cloud function destinations, such as Google Cloud Function and AWS Lambda destinations, can increase the payload size and potentially hit payload limits.

Subscribe to notifications

Subscriptions allow you to receive notifications after a resource is modified or an event occurs. Subscriptions are commonly used to trigger asynchronous background processes. For example, by subscribing to the Customer Created and Customer Email Changed Messages, you can implement a system which sends verification emails when these notifications are received.

Composable Commerce provides three notification payload types through Subscriptions:

  • Messages represent changes or actions performed on Project resources, such as Orders, Products, or Customers. They are associated with API queryable resources and include comprehensive metadata such as version and sequenceNumber fields to maintain consistency and ordering.
  • Changes represent updates to a subscribed resource. The payload includes details about whether the resource was created, updated, or deleted.
  • Events represent changes or actions that occur across a broader range of services and use cases. Unlike Messages, Events are not associated with API queryable resources. This design allows Events to support notifications for services beyond the HTTP API, such as Import API, Checkout, and Merchant Center. Events typically contain fewer required fields than Messages, making them simpler and more flexible for diverse notification scenarios.

Use Messages when you need notifications about changes to core Composable Commerce resources. Use Changes when you need a concise payload that indicates whether a resource was created, updated, or deleted. Use Events when you need notifications from services like Import API or for use cases that extend beyond traditional Project resources.

Implement workflows

States allow you to model finite state machines reflecting custom business logic, and are ideal for creating custom workflows. For example, to implement an approval process for new Reviews, you could create the States pending-approval and approved to manage this process.