課題
- 配列の長さが 1 の場合、JSONata 式
$map
の評価結果が オブジェクトとして扱われる。
Map
ステートでは、Items
に 配列形式 が必須であるため、エラーが発生。
解決策
次の JSONata 式を使用することで、$map
の結果が 常に配列形式 で返されるようにした
"Items": "{% $type($map($states.input.hoges, function($hoge) { $merge([$hoge, {\"fuga\": $states.input.fuga}]) })) = 'array' ? $map($states.input.hoges, function($hoge) { $merge([$hoge, {\"fuga\": $states.input.fuga}]) }) : [$map($states.input.hoges, function($hoge) { $merge([$hoge, {\"fuga\": $states.input.fuga}]) })] %}"
具体的な対応手順
$type
を使用して配列形式をチェック
$type($map(...))
で結果が 'array'
かどうかを判定。
配列でない場合は明示的にラップ
- オブジェクトで評価された場合は、
[...]
を使って配列化。
$merge
を使用して追加フィールドを統合
- 各要素に
fuga
フィールドを追加するために $merge
を使用。
最終的なステートマシンの設定例
{
"Comment": "A description of my state machine",
"StartAt": "Lambda Invoke",
"States": {
"Lambda Invoke": {
"Type": "Task",
"Resource": "arn:aws:states:::lambda:invoke",
"Output": "{% $states.result.Payload %}",
"Arguments": {
"FunctionName": "arn:aws:lambda:ap-northeast-1:XXXXXXXXXXXX:function:test-lambda1:$LATEST",
"Payload": "{% $states.input %}"
},
"Retry": [
{
"ErrorEquals": [
"Lambda.ServiceException",
"Lambda.AWSLambdaException",
"Lambda.SdkClientException",
"Lambda.TooManyRequestsException"
],
"IntervalSeconds": 1,
"MaxAttempts": 3,
"BackoffRate": 2,
"JitterStrategy": "FULL"
}
],
"Next": "Map"
},
"Map": {
"Type": "Map",
"ItemProcessor": {
"ProcessorConfig": {
"Mode": "INLINE"
},
"StartAt": "Lambda Invoke (1)",
"States": {
"Lambda Invoke (1)": {
"Type": "Task",
"Resource": "arn:aws:states:::lambda:invoke",
"Output": "{% $states.result.Payload %}",
"Arguments": {
"FunctionName": "arn:aws:lambda:ap-northeast-1:XXXXXXXXXXXX:function:test-lambda2:$LATEST",
"Payload": "{% $states.input %}"
},
"Retry": [
{
"ErrorEquals": [
"Lambda.ServiceException",
"Lambda.AWSLambdaException",
"Lambda.SdkClientException",
"Lambda.TooManyRequestsException"
],
"IntervalSeconds": 1,
"MaxAttempts": 3,
"BackoffRate": 2,
"JitterStrategy": "FULL"
}
],
"End": true
}
}
},
"End": true,
"Items": "{% $type($map($states.input.hoges, function($hoge) { $merge([$hoge, {\"fuga\": $states.input.fuga}]) })) = 'array' ? $map($states.input.hoges, function($hoge) { $merge([$hoge, {\"fuga\": $states.input.fuga}]) }) : [$map($states.input.hoges, function($hoge) { $merge([$hoge, {\"fuga\": $states.input.fuga}]) })] %}"
}
},
"QueryLanguage": "JSONata"
}
動作確認
以下の入力データで動作を確認済み:
hoges
が複数要素の配列の場合
{
"hoges": [
{ "id": 1, "name": "Hoge A" },
{ "id": 2, "name": "Hoge B" }
],
"fuga": "example_fuga"
}
出力
[
{ "id": 1, "name": "Hoge A", "fuga": "example_fuga" },
{ "id": 2, "name": "Hoge B", "fuga": "example_fuga" }
]
hoges
が単一オブジェクトの場合
{
"hoges": { "id": 1, "name": "Hoge A" },
"fuga": "example_fuga"
}
出力
[
{ "id": 1, "name": "Hoge A", "fuga": "example_fuga" }
]
まとめ
要素数1でも、2~でも対応可能になった。