Skip to main content

Orchestration Components

Here are the main features of a DX Component:

  • May or may not use a Connection
  • Can retrieve data directly from the backend system via the Connection or from other Orchestration Components
  • Can be passed a real-time Context, which may be received from the client application or set by one of the other Orchestration Components
  • May or may not process business rules to drive aspects of the business logic based on the Context passed to it
  • Can cache it's response to avoid unnecessarily calling backend APIs or process information that has already been processed
  • Can manipulate and transform data received from various inputs
  • Can be chained with other Orchestration Components

Note: Orchestration Components are NOT the same as UI Components. They may provide the data that can be consumed by the UI Component, but do not provide any HTML/CSS or any other framework specific code/markup.

Creating a Component

  1. Navigate to Manage Experiences > Experience Component.
  2. Click the “+ Add Component” button to create a new Component.
  3. In the form modal, enter the following information:
    • Component Code: This is a unique name for the Component.
    • Component Name: A friendly name for the Component.
    • Component Description: A description of what the Component does
    • Logo: The URL to a logo to be associated with the Component (will default if left empty).
    • Is Asynchronous: If checked, this Component will be executed asynchronously and the DX Engine response will not wait for it to complete. If this Component is depended upon by any synchronous Component, this component will be executed synchronously.
    • No Rules: Check this box if Component will have no Experience Rules associated with it.alt_text
  4. In the Component Type field, select the type of Component you want to create.
  5. Click Submit.

After you have saved this initial set up, the new Component will be added to the Component listing. Click the Component's Edit button to complete configuration.

Component Naming Conventions

Since Components make an API call which perform a CRUD operation, it is good to have a descriptive name - <Action performed> <Resource/noun> <SaaS used(optional)>. For example:

  • Get Cart ID
  • Get Hero Banner - Cloudinary
  • Remove Items from Cart

If you use any mapper, data transformation script, or metadata Components, you can prefix the Component with Model, Mapper, Metadata, Transform, etc to give a clear indication that this Component performs data manipulation. For example:

  • Mapper - Hero Banner - Cloudinary
  • Model - Featured Products

Component Configurations

All Orchestration Components have some sort of configuration that controls the Component's behaviour. Some behaviours include:

  • Select the content type in which to fetch specific content records
  • Determine the search index to query
  • Choose a promotion to offer
  • Specify a value to transform
  • Select a collection to write to
  • Provide a list of products to remove from inventory
  • Determine whether the Component should do anything at all

To Configure a Component:

  1. Find the Component in the listing.
  2. Click on Component's Edit button.

Many configurations can use values that are determined at query-time via Expressions.

There are three different methods of specifying configuration values:

MethodDescription
LiteralA hardcoded configuration value is specified within the Component at setup-time.
Context FieldThe configuration value is determined at query-time by using the value from the specified Context Field.
JS ExpressionThe configuration value is determined at query-time by evaluating an expression (which has access to all Context Fields and Component results)

There are a common set of configurations that all DX Engine Components have. Depending on the type of Component, there are configurations that are specific to a Component.

Common Configurations

NameAPI PropertyUses ExpressionsDescription
Context Field EnrichmentscontextFieldEnrichmentYesUses the Component's response to calculate values to be put into the Context for other Orchestration Components to reference. See details here.
Sub ComponentssubComponentsYesProvides a way to enrich each record in a Component's response with the results of other Component executions using custom Contexts. See details here.
CachedcacheConfig.cachedNoIf set to true, the responses of this Component will be cached. The default value is false.
Cache Time-to-livecacheConfig.cacheTtlNoThe number of seconds that cached responses will be cached.
Cache Tag ConfigurationcacheConfig.cacheTagsNoA list of tags that will be associated with the cached response. See details here
Trigger ExpressiontriggerYesThe default value is true.
Validity ExpressionvalidityYesThe default value is true.
Skip on Failed DependencyskipOnFailedDependencyNoThe Component's execution is skipped if any of the Components on which it depends, is in a FAILED state.
Skip on Skipped DependencyskipOnSkippedDependencyNoThe Component's execution is skipped if any of the Components on which it depends, is in a SKIPPED state.
Skip on Invalid DependencyskipOnInvalidDependencyNoThe Component's execution is skipped if any of the Components on which it depends, is in an INVALID state.
MetadatametadataNoKey/value pairs with additional metadata to include on this Component.
Response TransformresponseTransformYesModifies (or completely overwrites) the Component's response.
Note

The API Property is the corresponding property to update via the Management API.

Component-Specific Configuration

Component-specific configurations are dependent upon the specific Component Type. The available configurations for each Component are documented on that Component's documentation page.

See Configuring Components for more information.

Expressions

Expressions allow for query-time evaluation of values using JavaScript syntax. Example: response.customerSegment and componentResponse('myComponent').

Depending on where an expression is used, it has access to different set of variables/functions.

All expressions have access to the following Javascript variables/functions:

Variable/FunctionDescription
_Lodash utility
encodeURINative Javascript function
encodeURIComponentNative Javascript function
JSONNative Javascript Object
ArrayNative Javascript Object
PromiseNative Javascript Object
ObjectNative Javascript Object
DateTimeDate and Time manipulation utility from the luxon library

Expressions used for Component-specific query parameters

When a new Component Type is created such as commercetools Dynamic Record List or Contentful Static Record List, specific parameters are made available to query these backends. For instance, a dynamic record list for commercetools requires Category ID to be passed to commercetools. You can also pass values such as Sort, Filter, etc.

Variable/FunctionDescriptionExample
contextField(contextField)Pass a value from the Context Field as a Query Parameter.contextField('categoryID')
componentResponse(componentCode)Pass a value from an upstream Component response as a Query Parameter`_.castArray(componentResponse('fetchProductIDs').productIDs)
componentStatus(componentCode)Check to see if an upstream Component was processed successfullycomponentStatus('fetchProductIDs')

Expressions used for Triggers

These expressions are evaluated to determine whether the current Component should be processed. The expression is expected to return a boolean value (true or false). However, if it returns a non-boolean value, the DX Engine will determine the Component's processing based on the 'truthiness' or 'falsiness' of that value. In JavaScript, certain values are inherently falsy (e.g., false, 0, "" (empty string), null, undefined, NaN), while all other values are considered truthy. This behavior allows for flexible expression evaluations in determining the processing logic of the Component.

Variable/FunctionDescriptionExample
contextField(contextField)Fetch the value of the Context Field by NamecontextField('location')==='US'
componentResponse(componentCode)Fetch the response of an upstream Component_.castArray(componentResponse('fetchProductIDs').productIDs).length > 0
componentStatus(componentCode)Check the status of an upstream ComponentcomponentStatus('callCustomerDatabase')==='VALID'

Expressions used for Validity

These expressions check for the Validity of the response of the Component currently being processed. The expression is expected to return a boolean value (true or false). However, if it returns a non-boolean value, the DX Engine will determine the response validity on the 'truthiness' or 'falsiness' of the resulting value. In JavaScript, certain values are inherently falsy (e.g., false, 0, "" (empty string), null, undefined, NaN), while all other values are considered truthy.

Variable/Function
response
contextField(contextField)
componentResponse(componentCode)
componentStatus(componentCode)

Expressions used for Context Field Enrichments

Context Fields are available to all Components that are to be processed within the scope of a single Experience API call. Each Component has the ability to update the Context of the query and all downstream Components will always read the most up to date value of the Context.

Variable/FunctionDescriptionExample
responseResponse of the current Component being processedresponse.customerSegment
contextField(contextField)Fetch the value of the Context Field by NamecontextField('categoryID')

Expressions used for Sub Components

Variable/Function
response
Note

Component X becomes dependent upon Component Y when Component X uses any expression (anywhere within Component X's configurations) that contains:

  • uses contextField('someContextField') where someContextField is enriched by Component Y's Component Field Enrichments
  • uses componentResponse('componentB')
  • uses componentStatus('componentB')

Component Statuses

When a query is made to the DX Engine Experience API, all of the requested Components are processed. The following flowchart describes the various states that a Component goes through.

Component Statuses

StateDescription
PROCESSINGA request to the DX Engine has occurred and this Component is part of fulfilling the reponse. Uses the Trigger expression to determine if it should run. If so, the Component is executed (enters the EXECUTING state). Otherwise, this Component will not be executed (enters SKIPPED state).
WAITING_FOR_COMPONENT_DEPENDENCIESWaits for any Orchestration Components on which it depends to be complete (either of the following states: VALID, FAILED, SKIPPED). Afterwards, the engine determines if the Component should be skipped. It will be skipped if any of the Skip on xxx Dependency (see this) checks are satisfied. Otherwise, the Component is executed (enters the EXECUTING state)
EXECUTINGThe Component logic is run. If any failure occurs during the execution, it enters FAILED state. Otherwise, the Component enters VALID state. If a Validity expression was specified, it is evaluated. If it evaluates to false, the state moves to INVALID.
SKIPPEDThe Component was not executed.
VALIDThe Component's response is valid.
INVALIDThe Component's response is not valid.

Component Metadata

Metadata are key/value pairs that you define on Components. The metadata values are not part of the main Component response, but rather found in the Component @extras section where triggered Experience Rule data also lives.

{
"example-component": {
"@extras": {
"rule": {
"metadata": [],
"attributes": {}
},
"metadata": [
{
"key": "__typename",
"value": "Banner"
},
{
"key": "sort_order",
"value": "6"
}
]
},
"status": "VALID",
"response": {}
}
}

Context Field Enrichment

You can access a Component's metadata using the following expressions:

  • ._get(componentExtras('example-component'), 'metadata')
  • componentExtras('example-component').metadata
  • componentExtras('example-component').metadata.filter(entry => entry.key === '__typename')

Orchestration

With Expressions and Component Statuses, the DX Engine allows for many complex real-time orchestration scenarios.

Context Field Enrichment

After a Component is executed and it is valid, it will process its Content Enrichments (if any). Take the following Context Field Enrichment configuration.

Context Field Enrichment

After this Component is run and gets a response from whatever data source it is querying, it will evaluate each of the three expressions and put the value into the request's context so that other Orchestration Components can use it. If a Context Field already exists, its value will be overwritten.

If Component A references a Context Field that is enriched (via Context Field Enrichment) by Component B, then the DX Engine is aware that Component A depends on Component B and will ensure that:

  • Component B is executed, even if it was not explicitly requested by the DX Engine Query.
  • Component B is executed BEFORE Component A is executed.

Sub Components

After a Component is executed and it is valid, it will process its Sub Components (if any). Take the following Sub Component configuration on a given parent Component.

Sub Components

After the parent Component is run, it will:

  • If specified, modify the parent Component Response by evaluating the Response Transformation Expression.
  • Create a new Context that is a copy of the context available to the current Component with the addition of a new Context Field, actorIds. Note: This newly-created Context is only available to the specified Orchestration Components in the Sub Components configuration (actors).
  • Execute the the actors Component.
  • Add the response of the actors Component into the parent Component's response under the property, movieActors.

Sub Components will always be executed synchronously, even if they were configured to be asynchronous.This is because the results of the Sub Components are written back to the parent Component's (the Component that executed the Sub Components) response so the parent Component must wait for the Sub Components to complete.

When a Component has Sub Components, its response must be either an object or an array of objects. That is because each Sub Component's response will be "inserted" into the parent Component's response using a specified Property Name.

If the response of a Sub Component is an array, then any configured Sub Components will be executed once for each item in the array. Otherwise, if the parent Component's response is an object, the Sub Components will be executed once.

The Context Field Expression is a JavaScript expression that has access to a variable called response, which refers to the response of parent Component, or each item in the parent Component's response if that response is an array.

The Orchestration Components specified within another Component's Sub Component configuration may, themselves, have more Sub Components. There is no limit to this nesting. This "nested orchestration" is much like the possible nesting seen with GraphQL (but without the need to write resolver code!).

Display Templates

When records are displayed as part of an experience rule (or as part of a data grid in DX Graph), the look and feel of each record is controlled by the "display template". The display template is a snippet of HTML code that can contain elements of data combined with visual styling to make the record listing more visually friend to the business user.

alt_text

In the example above, the display template is defined to show elements of the record including the image, name and description.

Defining a Display Template

For 'Static' Components, you can configure a 'Display Template' to control the business user's editing experience. Here is how it's done:

  1. Navigate to the Components dashboard.
  2. Find the experience Component of interest.
  3. Click the Edit button.
  4. Under the "Options" portion of the Component, find the "Display Template" section.
  5. Click on the code view("< >") button to bring up the HTML editor.
  6. Define the display template. Here, you can include HTML as well as attributes of the record using the {{myAttribute}} syntax.
  7. Once done, click the code view button again to visualize the record look and feel.
  8. Save the Component

alt_text

In the example above, title, description and other attributes are defined as part of the display template. The actual name of the attribute will vary based on your collections schema mode. In most cases, the field code of the attribute can be used. If your target field is a nested field in the schema, simply define the path like in the example above.

Once the display template has been defined and saved, navigate back to the corresponding experience rule to see the updated look and feel of the records.

Sample Display Template

The following display template HTML generates the layout seen in the record list above with an image to the left and name and description to the right.

<div style="display:inline;text-align:left;">
<div style="display:inline;text-align:left;margin-right:20px;"><img src="{{Image_URL}}" height="75px" class="fr-fic fr-dii"></div>
<div style="vertical-align:top;display:inline-block;">
<div style="font-weight:600;font-size:1.5rem;margin-bottom:10px;">{{Name}}</div>
<div style="font-weight:400;font-size:1.2rem;margin-bottom:10px;">{{Header}}</div>
</div>
</div>

The DX Engine gives business users the ability to define what content should be seen by who, when and where. However, sometimes, you want to pass additional information to the calling application beyond the content or data fetched from external systems. Also, you want these options to be presented to the business user in an intuitive visual editor.

Using Component Attributes as Front-end Design Props

To empower digital teams to pass along additional information and directions to the frontend, the DX Engine offers Component Level Attributes. One of the use cases for Component Level Attributes is Design Props that the frontend could use to render itself. An example of this would be how you want the layout to be adjusted based on the context of the user. Or, it could be the styling that should be applied to the visual Component.

As an example, we have a Component that returns the hero banner. A business user may want to personalize the experience and show a full width banner in some cases but a split banner in other cases. This can be configured as an attribute. In this example, we'll call our attribute "layout" and setup the option for the user to select between "full width" and "split".

Setting Up Component Attributes

alt_text

  1. Navigate to the Components dashboard.
  2. Find the experience Component of interest (in our case a hero banner Component) and click Edit.
  3. In the tab selector (top right), select the "Attribute Definition" tab.
  4. Create a new attribute by clicking on the "Add another item" button.
  5. For the attribute, give it a property, name and description. In our case, ours will be called "layout".
  6. Under the configuration, select "List".
  7. In the List of Values area, this is where you can define the options the user will be able to select from as well as the properties of each option. We'll define an option for boxed, fullwidth and split (side by side). For each, we'll give it a display name, image and description. These will be used in the next step..
  8. In the Template part of the configuration, we can define how the defined options will show up visually. Here we'll define an HTML snippet that shows an image and name for each option.
  9. Save the Component.

Selecting an Attribute Option

Once the attribute definition(s) are setup, they automatically appear in the Experience Rule as part of the target experience section. Here you can see the options we setup.

alt_text

Using the Attributes

In the Component response, attributes are returned as part of the @extras section. This can be used by the front-end to drive additional behaviour related to the attribute.

alt_text

._get(componentExtras('cloudinary-hero-banner'), 'rule.attributes')

Types of Attributes

In order to provide user friendly editor experience for non-technical users, the DX Engine offers several types of Attributes:

NameDescription
TextPrompts the user to enter some text value. There is formatting for: JavaScript, JSON, Handlebars, Markdown, HTML
NumberPrompts the user to enter a numeric value.
CheckboxPrompts the user to check or uncheck a checkbox. This satisfies Yes/No; On/Off
Manual PicklistPrompts the user to pick a value from a dropdown. The available values are manually-provided during the configuration of a Component.
Component Response PicklistPrompts the user to pick a value from a dropdown. The available values are dynamically fetched from some other source using another Component. This allows you to fetch values, for example, another webservice or a delimited file from an S3 bucket.
Manual ListPrompts the user to re-order a list of values. The available values are manually-provided during the configuration of a Component
Component Response ListPrompts the user to re-order a list of values. The available values are dynamically fetched from some other source using another Component.

Common Component Attribute Configurations

Each Attribute has the following common configurations:

NamePropertyDescription
Attribute PropertyattributePropertyThe name of the property in the Component's JSON response that will store the value of the Attribute.
Attribute NameattributeNameThe display name of the Attribute when displayed to the business user.
Attribute DescriptionattributeDescriptionThe description of the Attribute when displayed to the business user.
Attribute RequiredattributeRequiredWhether the Attribute is required or optional.
Attribute TypevalueConfig.typeHow the value of the Attribute should be collected from the business user.

Component Attribute Configurations based on Attribute Type

Depending on the Attribute Type, the Attribute may have additional configurations.

NamePropertyDescription
Default Text ValuedefaultTextValueThe default value of the Attribute when the business user is setting up rules for a Component. This is only valid when Value Type is Text.
Default Number ValuedefaultNumberValueThe default value of the Attribute when the business user is setting up rules for a Component. This is only valid when Value Type is Number.
Default Checkbox ValuedefaultCheckboxValueThe default value of the Attribute when the business user is setting up rules for a Component. This is only valid when Value Type is Checkbox.
List of ValuesvalueConfig.listA hardcoded list of available values for the Attribute. The specified value is a JSON array of objects where each object must have a property called value. The value property is used to store the value of the Attribute. Each object may any other number of properties. These properties are used to display the available values to the business user in the UI using a Display Template. This is only valid when Value Type is Manual Pick List or Manual List.
Component CodevalueConfig.componentCodeThe code of the Component that will be used to retrieve the available values for the Attribute. This is only valid when Value Type is Component Response Pick List or Component Response List.
Display TemplatevalueConfig.displayTemplateA Handlebars HTML template used to display the available values to the business user in the UI. This is only valid when Value Type is Manual Pick List, Manual List, Component Response Pick List or Component Response List.

When hardcoding a list of available values for an Attribute (e.g. when the Value Type is Manual Pick List or Manual List), the specified value is a JSON array of objects where each object must have a property called value. The value property is used to store the value of the Attribute. Each object may have any other number of properties. These properties are used to display the available values to the business user in the UI using a Display Template. The Display Template is specified as a Handlebars HTML template.

When retrieving a list of available values for an Attribute from another Component (e.g. when the Value Type is Component Response Pick List or Component Response List), the Component Code of the Component that will be used to retrieve the available values must be specified. The result of the Component must be in the format described in List of Values. The Display Template is specified as a Handlebars HTML template.

Example of List of Values

[
{
"value": "layout01",
"name": "Layout One",
"logoUrl": "https://images.com/layout-01.png"
},
{
"value": "layout02",
"name": "Layout Two",
"logoUrl": "https://images.com/layout-02.png"
},
{
"value": "layout03",
"name": "Layout Three",
"logoUrl": "https://images.com/layout-03.png"
},
{
"value": "layout04",
"name": "Layout Four",
"logoUrl": "https://images.com/layout-04.png"
}
]