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"/>
The attributes that are in the workflowRef element are shown in the following table.
Table 1. workflowRef elements
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.

  1. Invocation. The workflow engine loads the referenced workflow.
  2. Context sharing. The referenced workflow runs in the same context as the parent workflow, sharing all variables and payment message data.
  3. Variable scope. Variables that are set by the referenced workflow are visible to the parent workflow after execution.
  4. 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 persist after the workflow completes.
  • The parent workflow can access these variables in subsequent nodes.
  • Variable names must be unique across parent and referenced workflows to avoid conflicts.
  • Referenced workflows can modify parent workflow variables.
Tip: Use a naming convention (for example, prefixes) to avoid variable name collisions between the parent and referenced workflows.

Success and failure

  • The workflowRef node succeeds if the referenced workflow completes successfully.
  • The workflowRef node fails if the referenced workflow fails.
  • Failure handling follows the same rules as regular nodes (the error handlers can catch it).

Use cases

The common validation logic is as shown in the following example.
<?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>
The routing decision logic is as shown in the following example.
<?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>
The enrichment workflows are as shown in the following example.
<?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

The nested references are shown in the following list.
Supported
A referenced workflow can contain workflowRef nodes.
️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>
Effective dating considerations are shown in the following list.
  • 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 workflowRef fails.
  • The referenced workflows need to have matching effective date ranges.
Performance considerations are shown in the following list.
  • Each workflowRef invocation loads the referenced workflow from cache.
  • Excessive nesting can impact performance.
  • Consider consolidating deeply nested workflows.

Best practices

Naming conventions are as shown in the following example.
<?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"/>
Variable prefixes are as shown in the following example.
<?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)