はじめに
愚直にChoieステートでデータのフィルタリングを行なっていたもの、JSONPathに変えたらシンプルで使いやすくなった話
結論
MapステートとChoiceステートを使ったフィルタリングがJSONPathを使えば不要になった。
どういうことか
下記のようなデータを受け取り、dataが100以上の値のtaskのみ後続処理させたい場合を例とする。
{
"tasks": [
{
"id": "task1",
"data": 100
},
{
"id": "task2",
"data": 99
},
{
"id": "task3",
"data": 1000
}
]
}
MapとChoiceを使うパターン
今までの私。
下記のようにtasks
をMapで分散処理させ、それぞれに対してChoiceで判断の処理をしていた。
{
"Comment": "A state machine that processes tasks",
"StartAt": "ParallelProcessing",
"States": {
"ParallelProcessing": {
"Type": "Map",
"ItemsPath": "$.tasks",
"Iterator": {
"StartAt": "CheckData",
"States": {
"CheckData": {
"Type": "Choice",
"Choices": [
{
"Variable": "$.data",
"NumericGreaterThanEquals": 100,
"Next": "Process"
},
{
"Variable": "$.data",
"NumericLessThanEquals": 99,
"Next": "Pass"
}
]
},
"Process": {
"Type": "Pass",
"End": true
},
"Pass": {
"Type": "Pass",
"End": true
}
}
},
"ResultPath": "$.results",
"End": true
}
}
}
この場合、data
が99以下の場合の逃げ道を作ってあげることが必要だったり(次のステートが無いと怒られるため)、なによりMap実行それぞれの結果が見づらい。
JSONPathを使うパターン
JSONPathを使ったフィルタリングを使用すると、下記のように1ステートで記載することができる。
{
"Comment": "using JSONPath",
"StartAt": "SelectAndProcess",
"States": {
"SelectAndProcess": {
"Type": "Pass",
"Parameters": {
"SuccessfulResult.$": "$.tasks[?(@.data >= 100)]"
},
"End": true
}
}
}
最後に
おまじない的に、$
を付ければ引数の値をステートの入力に使える。くらいにしかおもっていなかったのが恥ずかしい。