[AWS CDK] aws_stepfunctions.JsonPath ClassのMethod(stringAt、numberAtなど)の使いどころを確認してみた
こんにちは、CX事業本部 IoT事業部の若槻です。
AWS Step FunctionsをAWS CDKで実装する際に、aws_stepfunctions.JsonPath ClassのMethodを使うことによりJsonPathへのアクセスを定義することができます。
JsonPathへのアクセスを定義するMethodには次の4つがあるのですが、どれを使えばよいのか時々使い分けに困ることがあります。(特にstringAtとnumberAt)
- stringAt
- numberAt
- listAt
- objectAt
今回は、これらのMethodの使いどころについて確認してみました。
先に結論
stringAt、numberAt、listAt、objectAt、これらの使い分けはAWS CDKの実装における型ガードのためのものであり、BuildされたState Machine Definitionにおいてはすべて同じ定義となる。
public static stringAt(path: string): string
public static numberAt(path: string): number
public static listAt(path: string): string[]
public static objectAt(path: string): IResolvable
確認してみた
確認した環境は次のようになります。
$ npm ls typescript aws-cdk --depth=0 project@0.1.0 /Users/path/to/project ├── aws-cdk@2.29.1 └── typescript@3.9.10
Build後のDefinitionはどうなるか
まずstringAt
とnumberAt
を使用した場合に、Build後のDefinitionではどのようになるかを確認してみます。
AWS CDK v2(TypeScript)で次のようなCDKスタックを作成します。
import { Construct } from 'constructs'; import { aws_stepfunctions, Stack, StackProps } from 'aws-cdk-lib'; export class AwsAppStack extends Stack { constructor(scope: Construct, id: string, props: StackProps) { super(scope, id, props); const pass1 = new aws_stepfunctions.Pass(this, 'pass1', { parameters: { string_from_string: aws_stepfunctions.JsonPath.stringAt('$.string'), string_from_number: aws_stepfunctions.JsonPath.stringAt('$.number'), number_from_string: aws_stepfunctions.JsonPath.numberAt('$.string'), number_from_number: aws_stepfunctions.JsonPath.numberAt('$.number'), }, }); new aws_stepfunctions.StateMachine(this, 'stateMachine', { stateMachineName: 'stateMachine', definition: pass1, }); } }
- JsonPathから文字列型と数値型の値を
stringAt
とnumberAt
の両方で取得するようにし、違いを見てみます。
上記をCDK Deployしてスタックをデプロイします。すると次のようなDefinitionのState Machineが作成されます。アクセス先のパスは違えど、4つすべて同じ定義となっていますね。
{ "StartAt": "pass", "States": { "pass": { "Type": "Pass", "Parameters": { "string_from_string.$": "$.string", "string_from_number.$": "$.number", "number_from_string.$": "$.string", "number_from_number.$": "$.number" }, "End": true } } }
文字列型の値と数値型の値を持つ次の入力を指定してステートマシンを実行します。
{ "string": "12345", "number": 67890 }
すると実行が成功しました。
TaskのOutputは次の通りです。JsonPathによるアクセス先の値がそのまま取得されているだけです。当然ながら、Methodの違いによってアクセスがエラーとなったり、型が変換されたりはしていません。
{ "string_from_string": "12345", "number_from_number": 67890, "number_from_string": "12345", "string_from_number": 67890 }
stringAt
とnumberAt
のいずれを使用するかによって、Build後のDefinitionにおける差異は無いという結果となりました。
CDK実装におけるMethodの使い分け
Build後のDefinitionにおける差異は無い場合、CDK実装においてMethodを使い分ける意味は何でしょうか。
まずformat
Methodを使った実装の例を考えてみます。
(method) JsonPath.format(formatString: string, ...values: string[]): string
format
の第2以降の引数の型はstringです。それに対してstringAt
およびnumberAt
を指定した場合。
new aws_stepfunctions.Pass(this, 'pass2', { parameters: { formatted: aws_stepfunctions.JsonPath.format( '{}_{}', aws_stepfunctions.JsonPath.stringAt('$.string'), aws_stepfunctions.JsonPath.numberAt('$.string'), ), }, });
numberAt
の方のみ型ガードでエラーとなりました。
もう一例見てみます。
Waitの引数として指定するDurationは数値型で指定する必要があります。それに対してstringAt
およびnumberAt
を指定した場合。
new aws_stepfunctions.Wait(this, 'wait', { time: aws_stepfunctions.WaitTime.duration( Duration.minutes(aws_stepfunctions.JsonPath.numberAt('$.string')), ), }); new aws_stepfunctions.Wait(this, 'wait2', { time: aws_stepfunctions.WaitTime.duration( Duration.minutes(aws_stepfunctions.JsonPath.stringAt('$.string')), ), });
stringAt
の方のみ型ガードでエラーとなりました。
以上のようにstringAt
やnumberAt
を使用するMethodの型仕様によって使い分けることにより、JsonPathのアクセスによる取得結果の型を明確にしたコーディングを要請されます。
おわりに
AWS CDKのaws_stepfunctions.JsonPath ClassのMathod(stringAt、numberAtなど)の使いどころを確認してみました。
stringAt
やnumberAt
の使い分けを意識する必要の無い実装(Parameter引数など)と、意識する必要のある実装(format
やDuration
など)があり初めは混乱しましたが、分かってしまえば簡単ですね。
以上