Step Functionsステートマシンで実行したLambda関数の戻り値のペイロードをパースする
こんにちは、CX事業本部 IoT事業部の若槻です。
AWS Step Functionsステートマシンで実行したLambda関数の戻り値のペイロードをパースする方法を調べていたところ、ステートマシンからのLambda関数の実行のされ方は2種類あったので、それぞれについて確認してみました。
方法
AWS CDKで実装したステートマシンで確認してみます。
CDKコード
import * as cdk from '@aws-cdk/core'; import * as sfn from '@aws-cdk/aws-stepfunctions'; import * as tasks from '@aws-cdk/aws-stepfunctions-tasks'; import * as lambda from '@aws-cdk/aws-lambda'; import * as lambdaNodejs from '@aws-cdk/aws-lambda-nodejs'; export class AwsCdkAppStack extends cdk.Stack { constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) { super(scope, id, props); //Lambda関数 const lambdaFunc = new lambdaNodejs.NodejsFunction(this, 'lambdaFunc', { entry: 'src/lambda/sampleHandler.ts', handler: 'handler', runtime: lambda.Runtime.NODEJS_14_X, }); //Lambda関数実行タスク1 const lambdaInvokeTask1 = new tasks.LambdaInvoke( this, 'lambdaInvokeTask1', { lambdaFunction: lambdaFunc, resultSelector: { 'payload1.$': '$.Payload', }, } ); //Lambda関数実行タスク2 const lambdaInvokeTask2 = new tasks.CallAwsService( this, 'lambdaInvokeTask2', { service: 'lambda', action: 'invoke', parameters: { FunctionName: lambdaFunc.functionName, }, iamResources: [lambdaFunc.functionArn], iamAction: 'lambda:InvokeFunction', resultSelector: { 'payload2.$': 'States.StringToJson($.Payload)', }, } ); //ステートマシン new sfn.StateMachine(this, 'stateMachine', { definition: lambdaInvokeTask1.next(lambdaInvokeTask2), }); } }
さてステートマシンのタスクでLambda関数を実行するメソッドは、LambdaInvoke()
とCallAwsService()
の2つがあります。
Workflow Studioで言うと、LambdaInvoke()
はIntegration TypeがOptimized
のパターンに対応しており、
CallAwsService()
は[AWS SDK]のパターン対応しています。
そしてCallAwsService()
の場合は戻り値のペイロードが必ず文字列となるため、ステートマシンでJson形式の戻り値をパースしたい場合はStates.StringToJson()
を使用する必要があります。
Lambdaコード
戻り値のペイロードとして{ value: 123 }
というJsonを返すLambdaです。
export const handler = async () => { return { value: 123 }; };
動作
ステートマシンを実行して動作を見てみます。
LambdaInvoke()
を使用してLambdaを実行したタスクでは、Lambdaの戻り値のペイロードが{"value":123}
とJson形式となっており、そのままステートマシンで使用できる形式となっています。
CallAwsService()
を使用してLambdaを実行したタスクでは、Lambdaの戻り値のペイロードが"{\"value\":123}"
と文字列形式となっており、States.StringToJson()
を使用することでパースできています。
LambdaInvoke()とCallAwsService()のどちらを使えば良い?
LambdaInvoke()
を使用するのが良いかと思います。理由は下記となります。
- 大抵のステートマシンのタスクでは、AWSサービスのすべてのAPIパラメータを指定可能とするためには
CallAwsService()
を使用する必要があるが、LambdaInvoke()
に関してはLogType
以外のすべてのパラメータを指定可能となっているため。 LambdaInvoke()
の方が記述が簡単になるため。
まとめ
- ステートマシンで実行したLambda関数の戻り値のペイロードは、
LambdaInvoke()
を使用した場合は文字列化されないが、CallAwsService()
を使用した場合は文字列化されるためStates.StringToJson()
などでパースをする必要がある。 - 基本的には
LambdaInvoke()
を使用すれば良さそう。
以上