Subworkflows

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 Creating and updating an existing workflow and Executing 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]

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}"
          }
        }
      ]
    }
  }
    

Calling 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: "Sherlock"
                  last_name: "Holmes"
              result: output
          - call_subworkflow2:
              call: name_message
              args:
                  first_name: "Ada"
                  last_name: "Lovelace"
              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": "Sherlock",
              "last_name": "Holmes"
            },
            "result": "output"
          }
        },
        {
          "call_subworkflow2": {
            "call": "name_message",
            "args": {
              "first_name": "Ada",
              "last_name": "Lovelace"
            },
            "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 steps call_subworkflow and call_subworkflow2.
  • The two steps supply different inputs for the arguments first_name and last_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 of England for the country variable.
  • The subworkflow returns the message it constructs to the main workflow.
  • The steps in the main workflow store the results as output and output2, respectively.
  • The main workflow combines output and output2 into a single message and returns the result: Hello Sherlock Holmes from England. Hello Ada Lovelace from England.

For more information, see Calls.

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.

YAML

main:
  steps:
    - first:
        call: hello
        args:
          input: "Kristof"
        result: some_output
    - second:
        return: ${some_output}

hello:
  params: [input]
  steps:
    - first:
        return: ${"Hello "+input}

JSON

{
  "main": {
    "steps": [
      {
        "first": {
          "call": "hello",
          "args": {
            "input": "Kristof"
          },
          "result": "some_output"
        }
      },
      {
        "second": {
          "return": "${some_output}"
        }
      }
    ]
  },
  "hello": {
    "params": [
      "input"
    ],
    "steps": [
      {
        "first": {
          "return": "${\"Hello \"+input}"
        }
      }
    ]
  }
}