You can use subworkflows to define a piece of logic or a set of steps you want to call multiple times, simplifying the workflow definition. Subworkflows are similar to a function or routine in a programming language. They can accept parameters and return values, allowing you to create more complex workflows with a broader range of applications.
For information on basic workflow tasks, see Create and update an existing workflow and Execute a workflow.
Main block
If a workflow has a subworkflow, the main workflow must be placed in a main
block. Subworkflows are always defined after the main body of the workflow
definition:
YAML
main: steps: - STEP_NAME: ... ... SUBWORKFLOW_NAME: params: [PARAMETER_1,PARAMETER_2...] steps: - SUBWORKFLOW_STEP_NAME: ...
JSON
{ "main": { "steps": [ { "STEP_NAME": ... } ... ] }, "SUBWORKFLOW_NAME": { "params": "[PARAMETER_1,PARAMETER_2...]", "steps": [ { "SUBWORKFLOW_STEP_NAME": ... } ] } }
If you don't need to pass parameters to the subworkflow, delete the params
block. Note that any parameters must be enclosed in square brackets. For example:
params: [Street, ZipCode, Country]
Note that the steps
block is required inside a
SUBWORKFLOW_NAME
block. It can contain the following:
assign
call
for
parallel
raise
return
steps
switch
try
Default parameters in subworkflows
Subworkflows support default values for parameters. The default parameter value is used only if a parameter isn't provided as part of a subworkflow call.
YAML
SUBWORKFLOW_NAME: params: [PARAMETER_1, PARAMETER_2: DEFAULT_VALUE2...] steps: - SUBWORKFLOW_STEP_NAME: ...
JSON
{ "SUBWORKFLOW_NAME": { "params": "[PARAMETER_1,PARAMETER_2: DEFAULT_VALUE2...]", "steps": [ { "SUBWORKFLOW_STEP_NAME": ... } ] } }
For example, the following workflow can be called with or without a Country parameter, and if the Country is not specified, it defaults to "United States".
YAML
build_address: params: [Street, ZipCode, Country: "United States"] steps: - concatenate: return: ${Street + ", " + ZipCode + ", " + Country}
JSON
{ "build_address": { "params": [ "Street", "ZipCode", { "Country": "United States" } ], "steps": [ { "concatenate": { "return": "${Street + \", \" + ZipCode + \", \" + Country}" } } ] } }
Call a subworkflow
You call a subworkflow using the call
field within a workflow step in the main
workflow, optionally supplying arguments to pass to the subworkflow:
YAML
main: steps: - STEP_NAME: call: SUBWORKFLOW_NAME args: ARG_1: VALUE_1 ARG_2: VALUE_2 ... result: OUTPUT_VARIABLE SUBWORKFLOW_NAME: params: [PARAMETER_1,PARAMETER_2...] steps: - step_1: ...
JSON
{ "main": { "steps": [ { "STEP_NAME": { "call": "SUBWORKFLOW_NAME", "args": { "ARG_1": "VALUE_1", "ARG_2": "VALUE_2" }, "result": "OUTPUT_VARIABLE" } } ] }, "SUBWORKFLOW_NAME": { "params": ["PARAMETER_1,PARAMETER_2"...], "steps": [ { "step_1": ... } ] } }
If the subworkflow accepts parameters, you can pass arguments (ARG_1
,
ARG_2
) and their values (VALUE_1
,
VALUE_2
) to the workflow. If the subworkflow returns
anything, you can store the data in the OUTPUT_VARIABLE
.
This example defines a subworkflow named name_message
and calls it from the
main workflow:
YAML
main: steps: - call_subworkflow: call: name_message args: first_name: "Ada" last_name: "Lovelace" result: output - call_subworkflow2: call: name_message args: first_name: "Sherlock" last_name: "Holmes" result: output2 - return_message: return: ${output + " " + output2} name_message: params: [first_name, last_name, country: "England"] steps: - prepareMessage: return: ${"Hello " + first_name + " " + last_name + " from " + country + "."}
JSON
{ "main": { "steps": [ { "call_subworkflow": { "call": "name_message", "args": { "first_name": "Ada", "last_name": "Lovelace" }, "result": "output" } }, { "call_subworkflow2": { "call": "name_message", "args": { "first_name": "Sherlock", "last_name": "Holmes" }, "result": "output2" } }, { "return_message": { "return": "${output + \" \" + output2}" } } ] }, "name_message": { "params": [ "first_name", "last_name", { "country": "England" } ], "steps": [ { "prepareMessage": { "return": "${\"Hello \" + first_name + \" \" + last_name + \" from \" + country + \".\"}" } } ] } }
This workflow definition does the following:
- The main workflow calls the
name_message
subworkflow twice, from the stepscall_subworkflow
andcall_subworkflow2
. - The two steps supply different inputs for the arguments
first_name
andlast_name
, which are then passed to the subworkflow. - The subworkflow
name_message
takes the arguments passed to it and constructs a simple message, supplying the default value ofEngland
for thecountry
variable. - The subworkflow returns the message it constructs to the main workflow.
- The steps in the main workflow store the results as
output
andoutput2
, respectively. - The main workflow combines
output
andoutput2
into a single message and returns the result:Hello Ada Lovelace from England. Hello Sherlock Holmes from England.
For more information, see Calls.
Call a subworkflow in an expression
This example is identical to the preceding example except that the workflow calls the subworkflow using an expression. Note that expressions cannot contain calls to subworkflows with blocking steps.
YAML
main: steps: - call_subworkflow: assign: - output: ${name_message("Ada","Lovelace")} - call_subworkflow2: assign: - output2: ${name_message("Sherlock","Holmes")} - return_message: return: ${output + " " + output2} name_message: params: [first_name, last_name, country: "England"] steps: - prepareMessage: return: ${"Hello " + first_name + " " + last_name + " from " + country + "."}
JSON
{ "main": { "steps": [ { "call_subworkflow": { "assign": [ { "output": "${name_message(\"Ada\",\"Lovelace\")}" } ] } }, { "call_subworkflow2": { "assign": [ { "output2": "${name_message(\"Sherlock\",\"Holmes\")}" } ] } }, { "return_message": { "return": "${output + \" \" + output2}" } } ] }, "name_message": { "params": [ "first_name", "last_name", { "country": "England" } ], "steps": [ { "prepareMessage": { "return": "${\"Hello \" + first_name + \" \" + last_name + \" from \" + country + \".\"}" } } ] } }
Simple subworkflow
This sample implements a simple subworkflow. When a workflow has a subworkflow,
the main workflow must be placed in a main
block. Subworkflows are always
defined after the main body of the workflow definition.