Node reference (nodeRef)

A node reference (nodeRef) is a special task type that helps you to invoke another node from within a node. It promotes reusability and modularity by enabling nodes to call other nodes as subroutines, eliminating the need to duplicate node logic across multiple workflows.

Purpose

Node references promote reusability and modularity by enabling workflows to call other workflows as subroutines, similar to how functions call other functions in programming. Node references help you to do the following steps.

  • Reuse node logic. Define node logic once and reference it from multiple locations.
  • Reduce duplication. Eliminate the need to copy and paste node definitions.
  • Simplify maintenance. Update logic in one place and have all references automatically use the updated version.
  • Organize complex nodes. Break down large nodes into smaller, focused components.
  • Promote modularity. Create library nodes that can be shared across different workflows.

XML structure

The basic syntax for a workflow reference is as shown in the following example.

<?xml version="1.0"?>
<nodeRef name="NodeRefName" nodeName="ReferencedNodeName"/>
The attributes that are in the nodeRef element are shown in the following table.
Table 1. nodeRef elements
Attribute Required Description
name Yes The unique name for this node reference task within the parent workflow. This name is used for logging and debugging.
nodeName Yes The name of the node that needs to be invoked. This node needs to exist in the system and be accessible at runtime.

For example,

<?xml version="1.0"?>
<node name="PaymentValidation">
    <task name="CheckFormat" type="validation"/>
    
    <!-- Reference to a reusable verification node -->
    <nodeRef name="AccountVerifyRef" nodeName="AccountVerificationNode"/>
    
    <task name="FinalCheck" type="validation"/>
</node>

Behavior

When the workflow engine encounters a nodeRef node, the steps that occur are shown in the following list.

  1. Invocation. When the workflow engine encounters a nodeRef task, it loads the referenced node.
  2. Context sharing. The referenced node runs in the same context as the parent node, sharing all variables and payment message data.
  3. Assignment Execution. The referenced node's onEntry and onExit assignments execute normally.
  4. Task Execution. All tasks within the referenced node execute in sequence.
  5. Return. Control returns to the parent node after the referenced node completes.

Assignment handling

NodeRef executes both onEntry and onExit assignments from the referenced node. It indicates that the task is critical. For example,
xml
<!-- Referenced node with assignments -->
<node name="AgentVerificationNode">
    <onEntry>
        <assign field="refAgentAcct" value=""/>
        <assign field="refAgentBankCode" value=""/>
    </onEntry>
    
    <task name="LookupAgent" type="lookup"/>
    
    <onExit>
        <assign field="refAgentRC" value="SUCCESS"/>
    </onExit>
</node>
<!-- Parent node using nodeRef -->
<node name="PaymentRouting">
    <nodeRef name="AgentVerifyRef" nodeName="AgentVerificationNode"/>
    <!-- After nodeRef completes, refAgentRC will be set to "SUCCESS" -->
</node>
The order of execution is shown in the following list.
  • Referenced node's onEntry assignments execute.
  • Referenced node's tasks execute.
  • Referenced node's onExit assignments execute.
  • Control returns to the parent node.

Variable handling

nodeRef shares the variable scope as the parent workflow. It means the following.

  • Variables set in the referenced node persist after the node completes.
  • The parent node can access these variables in the subsequent nodes.
  • onEntry and onExit assignments execute as if the node were inline
  • Variable names must be unique across to avoid conflicts.
  • Referenced nodes can modify parent node variables.
Tip: Use a naming convention (for example, ref prefix) for variables set by referenced nodes to clearly indicate their source.

Success and failure

  • The nodeRef task succeeds if the referenced node completes successfully.
  • The nodeRef task fails if the referenced node fails.
  • The referenced node's success or failure status is determined by the following.
    • Task execution results
    • onExit assignment stopResults values (if set)
    • Error conditions during execution

Use cases

The agent bank verification logic is as shown in the following example.
<?xml version="1.0"?>
<!-- Reusable agent verification node -->
<node name="IntermediaryAgentVerifyNode">
    <onEntry>
        <assign field="refAgentAcct" value=""/>
        <assign field="refAgentBankCode" value=""/>
        <assign field="refAgentName" value=""/>
    </onEntry>
    
    <task name="LookupAgentBank" type="lookup">
        <!-- Lookup logic -->
    </task>
    
    <task name="ValidateAgentAccount" type="validation">
        <!-- Validation logic -->
    </task>
    
    <onExit>
        <assign field="refAgentRC" value="SUCCESS"/>
    </onExit>
</node>
<!-- Multiple nodes can reference it -->
<node name="EuroPaymentRouting">
    <task name="DetermineRoute" type="decision"/>
    <nodeRef name="Agent1Verify" nodeName="IntermediaryAgentVerifyNode"/>
    <task name="ApplyRouting" type="assignment"/>
</node>
<node name="NordicPaymentRouting">
    <task name="CheckCurrency" type="validation"/>
    <nodeRef name="Agent2Verify" nodeName="IntermediaryAgentVerifyNode"/>
    <task name="SetRoutingFields" type="assignment"/>
</node>
The settlement account determination logic is as shown in the following example.
<?xml version="1.0"?>
<!-- Reusable settlement node -->
<node name="NextAgentSettlementNode">
    <onEntry>
        <assign field="refNextAgentSttlAcct" value=""/>
        <assign field="refNextAgentSttlMethod" value=""/>
    </onEntry>
    
    <task name="DetermineSettlement" type="lookup">
        <!-- Settlement logic -->
    </task>
    
    <onExit>
        <assign field="refNextAgentRC" value="COMPLETE"/>
    </onExit>
</node>
<!-- Used in routing workflow -->
<node name="PaymentSettlement">
    <task name="ValidateAmount" type="validation"/>
    <nodeRef name="SettlementRef" nodeName="NextAgentSettlementNode"/>
    <!-- Can now use refNextAgentSttlAcct and refNextAgentRC -->
    <task name="ApplySettlement" type="assignment"/>
</node>
The common validation patterns are as shown in the following example.
<?xml version="1.0"?>
<!-- Reusable validation node -->
<node name="StandardAccountValidation">
    <onEntry>
        <assign field="validationResult" value="PENDING"/>
    </onEntry>
    
    <task name="CheckAccountFormat" type="validation"/>
    <task name="CheckAccountStatus" type="lookup"/>
    <task name="CheckAccountLimits" type="validation"/>
    
    <onExit>
        <assign field="validationResult" value="PASSED"/>
    </onExit>
</node>
<!-- Multiple workflows use the same validation -->
<node name="ACHProcessing">
    <nodeRef name="ValidateRef" nodeName="StandardAccountValidation"/>
    <task name="ProcessACH" type="processing"/>
</node>
<node name="WireProcessing">
    <nodeRef name="ValidateRef" nodeName="StandardAccountValidation"/>
    <task name="ProcessWire" type="processing"/>
</node>
The correspondent bank routing is as shown in the following example.
<?xml version="1.0"?>
<!-- Reusable correspondent routing node -->
<node name="CorrespondentBankNode">
    <onEntry>
        <assign field="corrBankBIC" value=""/>
        <assign field="corrBankName" value=""/>
        <assign field="corrBankCountry" value=""/>
    </onEntry>
    
    <task name="LookupCorrespondent" type="lookup"/>
    <task name="ValidateCorrespondent" type="validation"/>
    
    <onExit>
        <assign field="corrBankRC" value="FOUND"/>
    </onExit>
</node>
<!-- Used in international payment routing -->
<node name="InternationalRouting">
    <task name="CheckDestination" type="decision"/>
    <nodeRef name="CorrBankRef" nodeName="CorrespondentBankNode"/>
    <task name="ApplyCorrBank" type="assignment"/>
</node>

Restrictions and limitations

The nested references are explained in the following list.
Supported
A referenced node can contain nodeRef tasks.
️Depth Limit
No automatic depth limit enforcement (use with caution).
Circular references
Not allowed.

Invalid circular reference is as shown in the following example.

<?xml version="1.0"?>
<!-- NodeA references NodeB -->
<node name="NodeA">
    <nodeRef name="RefB" nodeName="NodeB"/>
</node>
<!-- NodeB references NodeA - CIRCULAR! -->
<node name="NodeB">
    <nodeRef name="RefA" nodeName="NodeA"/>
</node>
Task type restrictions are shown in the following list.
  • NodeRef is a task type, not a node type.
  • NodeRef tasks can appear within the <node> element only.
  • NodeRef tasks execute in sequence with other tasks in the node.
Effective dating considerations are shown in the following list.
  • The referenced node is loaded by using the same effective date as the parent node.
  • If the referenced node does not exist for that effective date, the nodeRef fails.
  • The referenced nodes need to have matching effective date ranges.
Performance considerations are shown in the following list.
  • Each nodeRef invocation loads the referenced node from cache.
  • Excessive nesting can impact performance.
  • Consider consolidating deeply nested nodes.

Best practices

Naming conventions are as shown in the following example.
<?xml version="1.0"?>
<!-- Use descriptive names that indicate purpose -->
<nodeRef name="AgentVerifyRef" nodeName="IntermediaryAgentVerifyNode"/>
<nodeRef name="SettlementRef" nodeName="NextAgentSettlementNode"/>
<nodeRef name="ValidationRef" nodeName="StandardAccountValidation"/>
Variable prefixes are as shown in the following example.
<?xml version="1.0"?>
<!-- Referenced node uses prefixes to avoid conflicts -->
<node name="AgentVerificationNode">
    <onEntry>
        <assign field="refAgentAcct" value=""/>
        <assign field="refAgentBankCode" value=""/>
        <assign field="refAgentName" value=""/>
    </onEntry>
    
    <onExit>
        <assign field="refAgentRC" value="SUCCESS"/>
    </onExit>
</node>
Documentation is as shown in the following example.
<?xml version="1.0"?>
<!-- Document what the reference does and what variables it sets/expects -->
<nodeRef name="AgentVerifyRef" nodeName="IntermediaryAgentVerifyNode"/>
<!-- 
    Input variables expected: agentBIC, agentCountry
    Output variables set: refAgentAcct, refAgentBankCode, refAgentName, refAgentRC-->
Design referenced nodes need to have a single, clear purpose. It is called single responsibility. Examples are shown in the following list.
  • Good: "AccountVerificationNode"
  • Good: "SettlementDeterminationNode"
  • Poor: "ValidateAndRouteAndSettleNode" (too many responsibilities)
Assignment strategy is as shown in the following example. Use onEntry assignments to initialize output variables.
<?xml version="1.0"?>
node name="ReusableNode">
    <onEntry>
        <!-- Initialize all output variables to safe defaults -->
        <assign field="refResult" value=""/>
        <assign field="refStatus" value="PENDING"/>
        <assign field="refErrorCode" value=""/>
    </onEntry>
    
    <!-- Tasks that populate these variables -->
    
    <onExit>
        <!-- Set final status -->
        <assign field="refStatus" value="COMPLETE"/>
    </onExit>
</node>