14

How can I pass my input to my output in a task in AWS Step Functions?

I'm aware of this question, and the docs:

If the value of ResultPath is null, that means that the state’s own raw output is discarded and its raw input becomes its result.

But what I need is:

  • Given my input
{
  "input": "my_input"
}
  • And my lambda output
{
  "output": "my_output"
}

I need to pass to the next state the following json:

{
  "input": "my_input",
  "output": "my_output"
}
Gustavo Lopes
  • 3,794
  • 4
  • 17
  • 57

3 Answers3

9

Two suggestions comes to mind, either Use ResultPath to Replace the Input with the Result, which allows you to

If you don't specify a ResultPath, the default behavior is as if you had specified "ResultPath": "$". Because this tells the state to replace the entire input with the result, the state input is completely replaced by the result coming from the task result.

For this option to work, the Lambda function must return the desired response:

{
  "input": "my_input",
  "output": "my_output"
}

Alternatively Use ResultPath to Include the Result with the Input in the Step Functions developer guide. Next, if if you change the return value from you Lambda to include just "my_output" you can specify "ResultPath": "$.output" to achieve the desired result:

{
  "input": "my_input",
  "output": "my_output"
}
matsev
  • 32,104
  • 16
  • 121
  • 156
  • 2
    Thank you! I actually ended up using another node with ResultPath, because I had more room to work on the step functions definition than the lambda. – Gustavo Lopes Oct 14 '19 at 12:31
9

For anyone who comes to this question, it's not possible to do what I asked, but what you can do is, according to the docs:

{
  "States": {
    "my-state": {
      "Type": "task",
      "ResultPath": "$.response"
    }
  }
}

This will append whatever the lambda returns into the response node, resulting in:

{
  "input": "my_input",
  "response": {
    "output": "my_output"
  }
}
Gustavo Lopes
  • 3,794
  • 4
  • 17
  • 57
1

For anyone coming to this question: It is possible to do this using ResultSelector and Intrinsic Functions and Context Object. There is no need to change output.

With input given as:

{ "input_key": "input_value" }

and state output given as:

{ "output_key": "output_value" }

then in the state add the following fields: the $.Payload field comes from lambda's output, if the state is not a lambda call, then check the output to merge the proper key

"ResultSelector": {"response.$": "States.JsonMerge($.Payload, $$.Execution.Input, false)"}, "OutputPath": "$.response"

as a result the task's output will contain the input and output merged flat, without some weird nested dictionaries, exactly as requested

4rk
  • 33
  • 6
  • 1
    Tip 1: if using the graphical UI, fill `Transform ... with ResultSelector` with `{"response.$": ...}` and `Filter ... with OutputPath` with `$.response`. Tip 2: If you are not using lamba, and you want to merge all input and output keys, use `"States.JsonMerge($, $$.Execution.Input, false)"}` (`$` without the `.Payload` selector will select all keys) – crypdick Mar 31 '23 at 19:47