Docs / Strand / advanced/nested-workflows
Nested Workflows
Call workflows from other workflows to create modular, reusable designs.
Flow Call Node
The Flow Call node allows you to execute another workflow as a step in your current workflow.
Configuration
- flow_id (required) - The ID of the workflow to call
- data (optional) - Custom data to pass to the called workflow
Example
- Create a workflow called "process-user"
- In your main workflow, add a Flow Call node
- Set
flow_idto "process-user" - Optionally pass custom data:
{
"user_id": "{{ payload.id }}",
"context": {
"source": "main_workflow"
}
}
If the Flow Call node is directly connected to the previous node, use payload instead of steps.node_id.output_payload.
Passing Data
Default Behavior
If you don't specify data, the current event's payload and metadata are automatically passed to the called workflow.
Custom Data
You can pass a custom data object that supports templating:
Direct connection:
{
"user_id": "{{ payload.id }}",
"timestamp": "{{ meta.received_at }}",
"nested_data": {{ payload | tojson }}
}
Non-direct access:
{
"user_id": "{{ steps.user_lookup.output_payload.id }}",
"timestamp": "{{ meta.received_at }}",
"nested_data": {{ steps.process.output_payload | tojson }}
}
Accessing Output
The output from a nested workflow is available through the Flow Call node:
{{ steps.flow_call_node.output_payload }}
{{ steps.flow_call_node.output_payload.result }}
Infinite Loop Prevention
Strand automatically prevents infinite loops by tracking the call chain. If a workflow tries to call itself (directly or indirectly), an error is raised:
Infinite loop detected: workflow 'workflow-id' is calling itself (directly or indirectly).
Call chain: workflow-a -> workflow-b -> workflow-a
Best Practices
Use descriptive workflow names
Makes it clear what each workflow does
Keep workflows focused
Each workflow should have a single responsibility
Document dependencies
Note which workflows call which others
Test incrementally
Test nested workflows individually before combining
Use Cases
Modular Processing
Break complex workflows into smaller, reusable pieces:
validate-input- Validates incoming dataprocess-data- Processes the validated datasend-notification- Sends notifications
Conditional Execution
Call different workflows based on conditions:
{% if payload.type == 'user' %}
{{ 'process-user-workflow' }}
{% else %}
{{ 'process-admin-workflow' }}
{% endif %}
Reusable Components
Create reusable workflow components:
- Authentication workflows
- Data transformation workflows
- Notification workflows
Tendrl