Configure workflow input and output in Step Functions - AWS Step Functions

Configure workflow input and output in Step Functions

In the previous topic, Run your workflow , you learned how to run your workflow. In this topic, you'll learn how to select, filter, and manipulate data as it passes between states.

A Step Functions execution receives JSON text as input and passes that input to the first state in the workflow. Individual states in a workflow receive JSON data as input and usually pass JSON data as output to the next state. By default, data passes from one state to the next state in the workflow unless you’ve configured the input and/or output. Understanding how the information flows from state to another, and learning how to filter and manipulate this data, is key to effectively designing and implementing workflows in Step Functions.

Step Functions provides the following filters to control the input and output data flow between states:

Note

Based on your use case, you may not need to apply all of these filters in your workflows.

InputPath

Selects WHAT portion of the entire input payload to be used as a task’s input. If you specify this field, Step Functions first applies this field.

Parameters

Specifies HOW the input should look like before invoking the task. With the Parameters field, you can create a collection of key-value pairs that are passed as input to an AWS service integration, such as an AWS Lambda function. These values can be static, or dynamically selected from either the state input or the workflow Context object.

ResultSelector

Determines WHAT to choose from a task's output. With the ResultSelector field, you can create a collection of key-value pairs that replace a state’s result and pass that collection to ResultPath.

Specifying state output using ResultPath in Step Functions

Determines WHERE to put a task's output. Use the ResultPath to determine whether the output of a state is a copy of its input, the result it produces, or a combination of both.

Filtering state output using OutputPath

Determines WHAT to send to the next state. With OutputPath, you can filter out unwanted information, and pass only the portion of JSON data that you care about.

Tip

The Parameters and ResultSelector filters work by constructing JSON, whereas the InputPath and OutputPath filters work by filtering specific nodes within a JSON data object, and the ResultPath filter works by creating a field under which the output can be added.

For more information about configuring input and output in your workflows, see Processing input and output in Step Functions.

Select specific portions of the raw input using the InputPath filter

Use the InputPath filter to select a specific portion of the input payload.

If you don't specify InputPath, its value defaults to $, which causes the state's task to refer to the entire raw input instead of a specific portion.

Step 1: Create a state machine

Important

Ensure that your state machine is under the same AWS account and Region as the Lambda function you created earlier.

  1. Use the Parallel state example you learned about in Tutorial 4 to create a new state machine. Make sure your workflow prototype looks similar to the following prototype.

  2. Configure the integrations for the check-identity and check-address Lambda functions. For information about creating the Lambda functions and using them in your state machine, see Step 1: Create the Lambda functions to perform the required checks and Step 2: Update the workflow – Add parallel tasks to be performed.

  3. For Payload, make sure you keep the default selection of Use state input as payload.

  4. Choose Next and then do the steps 1 through 3 in Step 1: Save the state machine of Tutorial 5 to create a new state machine. For this tutorial, name your state machine WorkflowInputOutput.

Step 2: Run the state machine

  1. On the WorkflowInputOutput page, choose Start execution.

  2. (Optional) Enter a custom execution name to override the generated default.

    Non-ASCII names and logging

    Step Functions accepts names for state machines, executions, activities, and labels that contain non-ASCII characters. Because such characters will not work with Amazon CloudWatch, we recommend using only ASCII characters so you can track metrics in CloudWatch.

  3. In the Input area, add the following JSON data as the execution input.

    { "data": { "firstname": "Jane", "lastname": "Doe", "identity": { "email": "jdoe@example.com", "ssn": "123-45-6789" }, "address": { "street": "123 Main St", "city": "Columbus", "state": "OH", "zip": "43219" } } }
  4. Choose Start execution.

  5. The state machine execution results in an error because you’ve not specified what parts of the execution input the check-identity and check-address Lambda functions must use to perform the required identity and address verification.

  6. Continue to Step 3 of this tutorial to fix the error.

Step 3: Use the InputPath filter to select specific parts of an execution input

  1. On the Execution Details page, choose Edit state machine.

  2. To verify the applicant’s identity as mentioned in the execution input provided in Step 2: Run the state machine, edit the Verify identity task definition as follows:

    ... { "StartAt": "Verify identity", "States": { "Verify identity": { "Type": "Task", "Resource": "arn:aws:states:::lambda:invoke", "InputPath": "$.data.identity", "Parameters": { "Payload.$": "$", "FunctionName": "arn:aws:lambda:us-east-2:123456789012:function:check-identity:$LATEST" }, "End": true } } } ...

    Consequently, the following JSON data becomes available as input for the check-identity function.

    { "email": "jdoe@example.com", "ssn": "123-45-6789" }
  3. To verify the applicant’s address as mentioned in the execution input, edit the Verify address task definition as follows:

    ... { "StartAt": "Verify address", "States": { "Verify address": { "Type": "Task", "Resource": "arn:aws:states:::lambda:invoke", "InputPath": "$.data.address", "Parameters": { "Payload.$": "$", "FunctionName": "arn:aws:lambda:us-east-1:123456789012:function:check-address:$LATEST" }, "End": true } } } ...

    Consequently, the following JSON data becomes available as input for the check-address function.

    { "street": "123 Main St", "city": "Columbus", "state": "OH", "zip": "43219" }
  4. Choose Start execution. The state machine execution now completes successfully.

Manipulate the selected input using the Parameters filter

While the InputPath filter helps you limit the raw JSON input you provide, using the Parameters filter, you can pass a collection of key-value pairs as input. These key-value pairs can either be static values that you define in your state machine definition, or values that are selected from the raw input using InputPath.

In your workflows, Parameters are applied after InputPath. Parameters help you specify how the underlying task accepts its input payload. For example, if the check-address Lambda function accepts a string parameter as input instead of the JSON data, you can use the Parameters filter to transform the input.

In the following example, the Parameters filter receives the input you selected using InputPath in Step 3: Use the InputPath filter to select specific parts of an execution input and applies the intrinsic function States.Format on the input items to create a string called addressString. Intrinsic functions help you perform basic data processing operations on a given input. For more information, see Intrinsic functions for JSONPath states in Step Functions .

"Parameters": { "addressString.$": "States.Format('{}. {}, {} - {}', $.street, $.city, $.state, $.zip)" }

Consequently, the following string gets created and is provided to the check-address Lambda function as input.

{ "addressString": "123 Main St. Columbus, OH - 43219" }

Configure output using the ResultSelector, ResultPath, and OutputPath filters

When the check-address Lambda function is invoked in the WorkflowInputOutput state machine, the function returns an output payload after performing the address verification. On the Execution Details page, choose the Verify address step and view the output payload inside Task result on the Step details pane.

{ "ExecutedVersion": "$LATEST", "Payload": { "statusCode": 200, "body": "{\"approved\":true,\"message\":\"identity validation passed\"}" }, "SdkHttpMetadata": { "AllHttpHeaders": { "X-Amz-Executed-Version": [ "$LATEST" ], ... ... "StatusCode": 200 }

Using ResultSelector

If you need to provide the result of the identity and address verification checks to the following states in your workflow, you can select the Payload.body node in the output JSON and use the StringToJson intrinsic function in the ResultSelector filter to format the data as required.

ResultSelector selects what is needed from the task output. In the following example, ResultSelector takes the string in $.Payload.body and applies the States.StringToJson intrinsic function to convert the string to JSON and puts the resulting JSON inside the identity node.

"ResultSelector": { "identity.$": "States.StringToJson($.Payload.body)" }

Consequently, the following JSON data is created.

{ "identity": { "approved": true, "message": "Identity validation passed" } }

As you work with these input and output filters, you might see runtime errors from invalid JSONpath expressions.

Using ResultPath

You can specify a location in the initial input payload to save a state’s task processing result using the ResultPath field. If you don't specify ResultPath, its value defaults to $, which causes the initial input payload to be replaced with the raw task result. If you specify ResultPath as null, the raw result is discarded and the initial input payload becomes the effective output.

If you apply the ResultPath field on the JSON data created using the ResultSelector field, the task result is added inside the results node in the input payload as shown in the following example:

{ "data": { "firstname": "Jane", "lastname": "Doe", "identity": { "email": "jdoe@example.com", "ssn": "123-45-6789" }, "address": { "street": "123 Main St", "city": "Columbus", "state": "OH", "zip": "43219" }, "results": { "identity": { "approved": true } } }

Using OutputPath

You can select a portion of the state output after the application of ResultPath to pass to the next state. With this approach, you can filter out unwanted information and pass along only the portion of JSON that you need.

In the following example, the OutputPath field saves the state output inside the results node: "OutputPath": "$.results". Consequently, the final output of the state, which you can pass to the next state is as follows:

{ "addressResult": { "approved": true, "message": "address validation passed" }, "identityResult": { "approved": true, "message": "identity validation passed" } }

Using console features to visualize the input and output data flows

You can visualize the input and output data flow between the states in your workflows using the Step Functions console’s Data flow simulator or Advanced view option in the Execution Details page.

Manipulate the selected input using the Parameters field

While the InputPath field helps you limit the raw JSON input you provide, using the Parameters field, you can pass a collection of key-value pairs as input. These key-value pairs can either be static values that you define in your state machine definition, or values that are selected from the raw input using InputPath.

In your workflows, Parameters are applied after InputPath. Parameters help you specify how the underlying task accepts its input payload. For example, imagine if the check-address Lambda function accepts a string parameter as input instead of the JSON data, you can use the Parameters field to transform the input.

In the following example, the Parameters field receives the input you selected using InputPath in the Select specific portions of the raw input using the InputPath filter section and applies the intrinsic function States.Format on the input items to create a string called addressString. Intrinsic functions help you perform basic data processing operations on a given input. For more information, see Intrinsic functions.

"Parameters": { "addressString.$": "States.Format('{}. {}, {} - {}', $.street, $.city, $.state, $.zip)" }

Consequently, the following string gets created and is provided to the check-address Lambda function as input.

Note

If you update your input using this example and run the state machine, it returns an error because the Lambda function doesn’t accept the input in the updated format.

{ "addressString.$": "123 Main St. Columbus, OH - 43219" }

Next steps

In the final topic, Debug errors, you’ll learn how to debug errors in your Step Functions workflows.