The step function receives some input and looks up a bunch more and after that I want to add the result of a States.Format function to that input at the top level. I don't know all the input when the States.Format function is run so I need to keep all that input. Also the result of the States.Format function has to be at the top level - not in a sub-object.
If I use the Pass state to add the States.Format output then
Result only allows literal strings so that won't work:
Prepare Interaction:
Type: Pass
Result: States.Format('payment/receipt of {} made today', $.receiptValue)
ResultPath: $.interactionText
Next: Create Interaction
when passed:
{ ..., ReceiptValue: 123, ... }
produces:
{ ..., ReceiptValue: 123, ..., interactionText: "States.Format('payment/receipt of {} made today', $.receiptValue)" }
Parameters creates a key-value pair and ResultPath requires a separate key so the result is not at the top level:
Prepare Interaction:
Type: Pass
Parameters:
interactionText.$: States.Format('payment/receipt of {} made today', $.receiptValue)
ResultPath: $.interactionText
Next: Create Interaction
when passed:
{ ..., ReceiptValue: 123, ... }
produces:
{ ..., ReceiptValue: 123, ..., interactionText: { interactionText: "payment/receipt of 123 made today" }}
Even if you grab all the input with Parameters there is no way to add an item to it:
Prepare Interaction:
Type: Pass
Parameters:
Payload.$: $
Payload.interactionText.$: States.Format('payment/receipt of {} made today', $.receiptValue)
OutputPath: $.Payload
Next: Create Interaction
when passed:
{ ..., ReceiptValue: 123, ... }
produces:
{ ..., ReceiptValue: 123, ..., "Payload.interactionText": "payment/receipt of 123 made today" }
There is no way to remove the key from Parameters and just using ResultPath: $ doesn't keep the input. Is there any way to get a step function to produce
{ ..., ReceiptValue: 123, ..., interactionText: "payment/receipt of 123 made today" }
either using a Pass state or some other method that doesn't call a lambda?
Here is the entire step function:
StateMachine:
definition:
StartAt: Retrieve Customer Profile
States:
Retrieve Customer Profile:
Type: Task
Resource: arn:aws:states:::lambda:invoke
OutputPath: $.Payload
Parameters:
Payload.$: $
FunctionName: !GetAtt RetrieveCustomerProfile.Arn
Next: Prepare Interaction
Prepare Interaction:
Type: Pass
OutputPath: $.Payload
Parameters:
Payload.$: $
Payload.interactionText.$: States.Format('payment/receipt of {} made today by {}', $.receiptValue, $.phoneNumber)
Next: Create Interaction
Create Interaction:
Type: Task
Resource: arn:aws:states:::lambda:invoke
OutputPath: $.Payload
Parameters:
Payload.$: $
FunctionName: !GetAtt CreateInteraction.Arn
Next: End
End:
Type: Succeed
You probably want to use the States.JsonMerge intrinsic function for this. The example below shows how to this with a series of Pass States.
{
"Comment": "An example to demonstrate merging keys into a single object",
"StartAt": "Simulate Function Output",
"States": {
"Simulate Function Output": {
"Type": "Pass",
"Result": {
"receiptValue": 25,
"otherValue1": "some string",
"otherValue2": "some other string"
},
"Next": "Augment"
},
"Augment": {
"Type": "Pass",
"Parameters": {
"origional.$": "$",
"new": {
"interactionText.$": "States.Format('payment/receipt of {} made today', $.receiptValue)"
}
},
"Next": "Merge"
},
"Merge": {
"Type": "Pass",
"End": true,
"Parameters": {
"merged.$": "States.JsonMerge($.origional, $.new, false)"
},
"OutputPath": "$.merged"
}
}
}
For your specific example though, you shouldn't need to have any Pass states. Imagine you have a function called myFirstFunction that returns this as a response. Then you want to pass the merged object to mySecondFunction.
{
"receiptValue": 25,
"otherValue1": "some string",
"otherValue2": "some other string"
}
This is how you could do it without needing a Pass state.
{
"Comment": "A description of my state machine",
"StartAt": "Lambda Function 1",
"States": {
"Lambda Function 1": {
"Type": "Task",
"Resource": "arn:aws:states:::lambda:invoke",
"Parameters": {
"Payload.$": "$",
"FunctionName": "myFirstFunction"
},
"ResultSelector": {
"raw.$": "$.Payload",
"extra": {
"interactionText.$": "States.Format('payment/receipt of {} made today', $.Payload.receiptValue)"
}
},
"Next": "Lambda Function 2"
},
"Lambda Function 2": {
"Type": "Task",
"Resource": "arn:aws:states:::lambda:invoke",
"OutputPath": "$.Payload",
"Parameters": {
"Payload.$": "States.JsonMerge($.raw, $.extra, false)",
"FunctionName": "mySecondFunction"
},
"End": true
}
}
}
You will see that I use ResultSelector to do the augmentation before returning the result from the first Lambda function. Then I use States.JsonMerge to merge before sending to the second function.
The second function will then get the following, which I think is what you wanted:
{
"receiptValue": 25,
"otherValue2": "some other string",
"otherValue1": "some string",
"interactionText": "payment/receipt of 25 made today"
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With