Workflow reference (workflowRef)
A workflow reference (workflowRef) is a special node type that helps you to invoke
another workflow from within a workflow.
Overview
Workflow references promote reusability and modularity by enabling workflows to call other workflows as subroutines, similar to how functions call other functions in programming. Workflow references help you to do the following.
- Reuse common logic. Define workflow logic once and reference it from multiple workflows.
- Reduce duplication. Eliminate the need to copy and paste workflow definitions.
- Simplify maintenance. Update logic in one place and have all references automatically use the updated version.
- Organize complex workflows. Break down large workflows into smaller, manageable components.
- Promote modularity. Create library workflows that can be shared across different business processes.
XML structure
The basic syntax for a workflow reference is as shown in the following example.
<?xml version="1.0"?>
<workflowRef name="WorkflowRefName" workflowName="ReferencedWorkflowName"/>
workflowRef element are shown in the following table.
| Attribute | Required | Description |
|---|---|---|
| name | Yes | The unique name for this workflow reference node within the parent workflow. This name is used for logging and debugging. |
| workflowName | Yes | The name of the workflow to be invoked. This workflow needs to exist in the system and be accessible at runtime. |
For example,
<?xml version="1.0"?>
<workflow name="MainPaymentWorkflow">
<node name="ValidatePayment">
<task name="CheckAmount" type="validation"/>
</node>
<!-- Reference to a reusable validation workflow -->
<workflowRef name="CommonValidationRef" workflowName="CommonValidationWorkflow"/>
<node name="ProcessPayment">
<task name="ApplyFees" type="calculation"/>
</node>
</workflow>
Behavior
When the workflow engine encounters a workflowRef node, the steps that occur are shown in
the following list.
- Invocation. The workflow engine loads the referenced workflow.
- Context sharing. The referenced workflow runs in the same context as the parent workflow, sharing all variables and payment message data.
- Variable scope. Variables that are set by the referenced workflow are visible to the parent workflow after execution.
- Return. Control returns to the parent workflow after the referenced workflow completes.
Variable handling
WorkflowRef shares the variable scope as the parent workflow. It means the following.
Variables set in the referenced workflow persistafter the workflow completes.The parent workflow can access these variablesin subsequent nodes.Variable names must be uniqueacross parent and referenced workflows to avoid conflicts.Referenced workflows can modify parent workflow variables.
Success and failure
- The
workflowRefnode succeeds if the referenced workflow completes successfully. - The
workflowRefnode fails if the referenced workflow fails. - Failure handling follows the same rules as regular nodes (the error handlers can catch it).
Use cases
<?xml version="1.0"?>
<!-- Reusable validation workflow -->
<workflow name="StandardPaymentValidation">
<node name="ValidateAmount">
<task name="CheckMinMax" type="validation"/>
</node>
<node name="ValidateAccount">
<task name="CheckAccountStatus" type="lookup"/>
</node>
</workflow>
<!-- Multiple workflows can reference it -->
<workflow name="ACHPayment">
<workflowRef name="ValidationRef" workflowName="StandardPaymentValidation"/>
<node name="ProcessACH">
<task name="CreateACHFile" type="processing"/>
</node>
</workflow>
<workflow name="WirePayment">
<workflowRef name="ValidationRef" workflowName="StandardPaymentValidation"/>
<node name="ProcessWire">
<task name="CreateWireMessage" type="processing"/>
</node>
</workflow><?xml version="1.0"?>
<!-- Reusable routing workflow -->
<workflow name="DeterminePaymentRoute">
<node name="CheckAmount">
<task name="AmountThreshold" type="decision"/>
</node>
<node name="CheckCurrency">
<task name="CurrencyRouting" type="lookup"/>
</node>
<!-- Sets routing variables: routingMethod, clearingSystem -->
</workflow>
<!-- Main workflow uses routing decision -->
<workflow name="PaymentProcessing">
<workflowRef name="RoutingRef" workflowName="DeterminePaymentRoute"/>
<!-- Use variables set by referenced workflow -->
<node name="ApplyRouting">
<task name="SetRoutingFields" type="assignment"/>
</node><?xml version="1.0"?>
<!-- Enrichment workflow that adds data -->
<workflow name="EnrichPaymentData">
<node name="LookupBankInfo">
<task name="GetBankDetails" type="lookup"/>
</node>
<node name="LookupFees">
<task name="CalculateFees" type="calculation"/>
</node>
<!-- Sets: bankName, bankAddress, feeAmount -->
</workflow>
<!-- Main workflow -->
<workflow name="PaymentPreparation">
<node name="BasicValidation">
<task name="CheckFormat" type="validation"/>
</node>
<workflowRef name="EnrichmentRef" workflowName="EnrichPaymentData"/>
<node name="FinalizePayment">
<task name="BuildMessage" type="processing"/>
</node>
</workflow>Restrictions and limitations
- Supported
- A referenced workflow can contain
workflowRefnodes. - ️Depth Limit
- Maximum nesting depth is 5 levels.
- Circular references
- Not allowed.
Invalid circular reference is as shown in the following example.
<?xml version="1.0"?>
<!-- WorkflowA references WorkflowB -->
<workflow name="WorkflowA">
<workflowRef name="RefB" workflowName="WorkflowB"/>
</workflow>
<!-- WorkflowB references WorkflowA - CIRCULAR! -->
<workflow name="WorkflowB">
<workflowRef name="RefA" workflowName="WorkflowA"/>
</workflow>
- The referenced workflow is loaded by using the same effective date as the parent workflow.
- If the referenced workflow does not exist for that effective date, the
workflowReffails. - The referenced workflows need to have matching effective date ranges.
- Each
workflowRefinvocation loads the referenced workflow from cache. - Excessive nesting can impact performance.
- Consider consolidating deeply nested workflows.
Best practices
<?xml version="1.0"?>
<!-- Use descriptive names that indicate purpose -->
<workflowRef name="ValidationRef" workflowName="StandardPaymentValidation"/>
<workflowRef name="RoutingRef" workflowName="DeterminePaymentRoute"/>
<workflowRef name="EnrichmentRef" workflowName="EnrichPaymentData"/>
<?xml version="1.0"?>
<!-- Referenced workflow uses prefixes to avoid conflicts -->
<workflow name="CommonValidation">
<node name="SetResults">
<assignment>
<assign field="val_isValid" value="true"/>
<assign field="val_errorCode" value=""/>
</assignment>
</node>
</workflow>Documentation is as shown in the following example.
<?xml version="1.0"?>
<!-- Document what the reference does and what variables it sets/expects -->
<workflowRef name="RoutingRef" workflowName="DeterminePaymentRoute"/>
<!--
Input variables expected: amount, currency, country
Output variables set: routingMethod, clearingSystem, priority-->
Design referenced workflows need to have a single, clear purpose. This is called single responsibility. Examples are shown in the following list.
Good: "ValidatePaymentAmount"Good: "DetermineRoutingMethod"Poor: "ValidateAndRouteAndEnrich" (too many responsibilities)