AWS StepFunctionsの変数機能をJSONPathで使ってみる

AWS StepFunctionsの変数機能をJSONPathで使ってみる

Clock Icon2025.03.31

こんにちは、AWS事業本部@福岡オフィスのべこみん(@beco_minn)です。

皆さん、AWS Step Functions(以下SFn)の変数は使ってますか?
変数とは昨年11月にリリースされた比較的新しめの機能で、この機能のおかげでステート間での値受け渡しが柔軟になりました。
詳しくは以下の記事をご参照ください。
[アップデート] AWS Step Functions で変数が使えるようになりました | DevelopersIO

また、同じタイミングでSFnにはJSONataと呼ばれる記法が導入されました。
JSONataは従来のJSONPath記法に比べてより柔軟に様々な処理が書けることもあり、現在SFnではJSONataを利用することが推奨されています。
JSONataの詳細については以下AWSブログをご参照ください。
変数と JSONata を使った AWS Step Functions での開発者エクスペリエンスの簡素化 | Amazon Web Services ブログ

同じタイミングでリリースされたこともあり、変数の記述サンプルはJSONataで書かれているものが多く、JSONPathでの書き方についてはなかなか記述されているものがありません。
そこで本記事では、実際にJSONPathで変数を取り扱ってみた結果を簡単にまとめてみました。

最初に簡単まとめ

  • 変数の設定は Assign で行う
    • 固定値を入れたい場合は "test_key": "test_value" このようにkeyもvalueもドルマークを付けずに書く
    • 前ステートからのinputなど変数を入れたい場合は "test_key.$": "$.test_value" のようにkeyにドルマークを付けて書く
  • 変数の使用は Parameters で行う
    • 参照は "result.$": "$test_key" のようにkeyとvalueにドルマークを付ける
  • 変数はChoiceなどのステートでも参照可能

やってみた

早速確認していきますが、その前にユーザーガイドを見てみましょう。

変数を使用して状態間でデータを渡す - AWS Step Functions

step-functions-jsonpath-variables_0

ユーザーガイドによると、上図の通りJSONPathでは変数の割り当て(Assign)はParametersから分岐しており、ResultSelector等のフローとは異なるフローで処理が行われるようです。

また、変数の割り当てはAssignで行われるためコードだと下記のような書き方になるようです。

# Example of Assign with JSONPath
{
  "Type": "Task",
  ...
  "Assign": {
    "products.$": "$.order..product",
    "orderTotal.$": "$.order.total"
  },
  "Next": "the next state"
}

それでは確認していきます。

前のステートからのInputを変数に設定する

まずは簡単にこんなステートマシンを作ってみました。

step-functions-jsonpath-variables_1

{
  "Comment": "A description of my state machine",
  "StartAt": "Output something",
  "States": {
    "Output something": {
      "Type": "Pass",
      "Next": "Assign variable",
      "Result": {
        "result_key": "result_value"
      }
    },
    "Assign variable": {
      "Type": "Pass",
      "Assign": {
        "test_key.$": "$.result_key"
      },
      "Next": "Use variables"
    },
    "Use variables": {
      "Type": "Pass",
      "End": true,
      "Parameters": {
        "final_result.$": "$test_key"
      }
    }
  },
  "QueryLanguage": "JSONPath"
}

内容としては、Output something ステートで "result_key": "result_value" という結果を出力し、その結果を Assign variable ステートで変数に "test_key.$": "$.result_key" と割り当てします。そして最後に Use variables ステートのParametersプロパティで "final_result.$": "$test_key" という風に変数を参照します。

最後の出力結果は下記のようになり、ちゃんと設定した変数が取得出来ていることが分かります。

{
  "final_result": "result_value"
}

固定値を変数に設定する

次は固定値を変数に設定するパターンです。

step-functions-jsonpath-variables_2

{
  "Comment": "A description of my state machine",
  "StartAt": "Assign variable",
  "States": {
    "Assign variable": {
      "Type": "Pass",
      "Assign": {
        "test_key": "test_value"
      },
      "Next": "Use variables"
    },
    "Use variables": {
      "Type": "Pass",
      "End": true,
      "Parameters": {
        "final_result.$": "$test_key"
      }
    }
  },
  "QueryLanguage": "JSONPath"
}

固定値を変数に設定する場合、value部分はもちろん、key部分にもドルマークは不要です。
ただし、参照する際にはちゃんとドルマークを使いましょう。

最後の出力結果は下記のようになります。

{
  "final_result": "test_value"
}

設定した変数をChoiceで参照する

設定した変数はChoiceステートでも参照可能です。

step-functions-jsonpath-variables_3

{
  "Comment": "A description of my state machine",
  "StartAt": "Assign variable",
  "States": {
    "Assign variable": {
      "Type": "Pass",
      "Assign": {
        "test_key": "test_value",
        "test_key_2": "test_value"
      },
      "Next": "Choice"
    },
    "Choice": {
      "Type": "Choice",
      "Choices": [
        {
          "Next": "成功",
          "Variable": "$test_key",
          "StringEqualsPath": "$test_key_2"
        }
      ],
      "Default": "Fail"
    },
    "Fail": {
      "Type": "Fail"
    },
    "成功": {
      "Type": "Succeed"
    }
  },
  "QueryLanguage": "JSONPath"
}

Choiceでは、ルール内のVariableとValueで変数の利用が可能です。
Valueで変数を利用する場合、String variable(StringEqualsPath)Number variable(NumericEqualsPath) を利用する必要がある点に注意が必要です。

設定した変数をLambdaに渡す

設定した変数はPayloadとしてLambdaに渡せます。

step-functions-jsonpath-variables_4

{
  "Comment": "A description of my state machine",
  "StartAt": "Assign variable",
  "States": {
    "Assign variable": {
      "Type": "Pass",
      "Assign": {
        "test_key": "test_value"
      },
      "Next": "Lambda Invoke"
    },
    "Lambda Invoke": {
      "Type": "Task",
      "Resource": "arn:aws:states:::lambda:invoke",
      "OutputPath": "$.Payload",
      "Parameters": {
        "FunctionName": "arn:aws:lambda:ap-northeast-1:123456789012:function:test_lambda:$LATEST",
        "Payload": {
          "test.$": "$test_key"
        }
      },
      "End": true
    }
  },
  "QueryLanguage": "JSONPath"
}

変数をLambda関数に渡したい場合はParametersのPayloadプロパティで "test.$": "$test_key" のように参照可能です。

Lambda関数の実行結果は以下のようになります。

{
  "statusCode": 200,
  "receivedEvent": {
    "test": "test_value"
  }
}

最後に

これから利用者が減少していくことが予想されるJSONPath記法ですが、魔改造気味に付け加えられたこの変数の書き方に苦しんでいる方は少なからず居るはず…と思い本記事を執筆してみました。
分かりやすさを重視してかなりシンプルな構成にしてみましたがいかがだったでしょうか。

本記事がどなたかのお役に立てば幸いです。

以上、べこみんでした。

Share this article

facebook logohatena logotwitter logo

© Classmethod, Inc. All rights reserved.