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 toResultPath
. 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.
Filtering and manipulating inputs and results
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.
To learn how to use the InputPath filter, perform the following steps:
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.
-
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. -
Configure the integrations for the
check-identity
andcheck-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. -
For Payload, make sure you keep the default selection of Use state input as payload.
-
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
-
On the WorkflowInputOutput page, choose Start execution.
-
(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.
-
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" } } }
-
Choose Start execution.
-
The state machine execution results in an error because you’ve not specified what parts of the execution input the
check-identity
andcheck-address
Lambda functions must use to perform the required identity and address verification. -
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
-
On the Execution Details page, choose Edit state machine.
-
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" }
-
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" }
-
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
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.