Problem
I need to transform the state machine input for a Task using the keys from one object (which we'll call obj1) in the input and a separate key-value pair in the input (which we'll call obj2). Several keys in obj1 are optional parameters so I can't assume the keys that will be present a priori. Additionally, several other key-value pairs may exist that are irrelevant to the Task and so shall not be included in the payload.
I'm specifically looking for a single Step Functions Task definition that solves this problem.
Example
State machine Task input:
{
"obj1": { "a": 1, "b": "foo" },
"obj2": { "c": 2, "d": "bar" },
"obj3": "baz",
"obj4": { ... }
}
Transformed input for Step Functions Task:
{
"payload": {
"a": 1,
"b": "foo",
"obj2": { "c": 2, "d": "bar" }
}
}
Attempts
I've been attempting to solve this problem using AWS Step Functions Intrinsic functions to no avail. States.JsonMerge won't work since I need the key "obj2" to be present in the payload object, and I don't want irrelevant key-value pairs such as "obj1", "obj3", or "obj4" to be in the payload. States.Format seemed promising using the below syntax, but it doesn't appear Amazon States Language (ASL) observes the spread operator. Not sure if it's a syntax issue or if it's simply not possible using ASL.
MyTask:
Type: Task
Resource: arn:aws-us-gov:states:::states:startExecution.sync:2
Parameters:
StateMachineArn: "${my_sfn_arn}"
Input:
payload.$: "States.Format({ ...$.obj1, 'obj2.$': $.obj2 })"
That Task definition failed to deploy with the following error message:
Resource handler returned message: "Invalid State Machine Definition: 'SCHEMA_VALIDATION_FAILED: The value for the field 'payload.$' must be a valid JSONPath or a valid intrinsic function call...
Note: I know this can be accomplished using a Lambda function, but this same problem exists in several Step Functions workflows so my question is only interested in an ASL-native solution for transforming the inputs.
Use the
JsonMergeintrinsic function to "spread"obj1's keys.Solution 1: Exactly match the expected output
Add a Pass state before
MyTaskto isolateobj2.Then merge that output with
obj1's keys. We referenceobj1from the execution's$$Context object:Solution 2: Simpler if the
obj1key can stayGiven your input, the task receives the 3 desired keys in the right shape, but keeps a redundant
obj1key: