Serverless FrameworkでStep Function (Map)
Map Stateの登場でかなりお世話になる度合いが上がりそうなStep Function。例によって堀家様のプラグインで触ってみます。 環境 プロジェクト作成 まずはいつも通りTypeScriptでプロジェクト作成。 […]
広告ここから
広告ここまで
目次
Map Stateの登場でかなりお世話になる度合いが上がりそうなStep Function。例によって堀家様のプラグインで触ってみます。
環境
$ sls -v
Framework Core: 1.54.0
Plugin: 3.1.2
SDK: 2.1.1
Components Core: 1.1.1
Components CLI: 1.2.3
プロジェクト作成
まずはいつも通りTypeScriptでプロジェクト作成。
$ sls create -t aws-nodejs-typescript -p sls-playground -n sls-playground
Serverless: Generating boilerplate...
Serverless: Generating boilerplate in "/Users/develop/sandbox/test/sls-playground"
_______ __
| _ .-----.----.--.--.-----.----| .-----.-----.-----.
| |___| -__| _| | | -__| _| | -__|__ --|__ --|
|____ |_____|__| \___/|_____|__| |__|_____|_____|_____|
| | | The Serverless Application Framework
| | serverless.com, v1.54.0
-------'
Serverless: Successfully generated boilerplate for template: "aws-nodejs-typescript"
$ cd sls-playground
$ yarn
Step Functionプラグイン追加
続いてプラグインも追加しましょう。
$ yarn add -D serverless-step-functions
$ vim serverless.yml
service:
name: sls-playground
plugins:
- serverless-webpack
# serverless-step-functionsを読み込むようにする
- serverless-step-functions
State Machineを定義する
YAML形式でState Machineの定義をやっていきましょう。
service:
name: sls-playground
plugins:
- serverless-webpack
- serverless-step-functions
provider:
name: aws
runtime: nodejs10.x
functions:
map:
handler: handler.map
mapTask:
handler: handler.mapTask
end:
handler: handler.end
stepFunctions:
stateMachines:
yourCatchMachine:
definition:
Comment: "A Catch example of the Amazon States Language using an AWS Lambda Function"
StartAt: HelloWorld
States:
HelloWorld:
Type: Task
Resource:
Fn::GetAtt: [map, Arn]
Next: mapped_task
mapped_task:
Type: Map
Iterator:
StartAt: CalcSquare
States:
CalcSquare:
Type: Task
Resource:
Fn::GetAtt: [mapTask, Arn]
End: true
Next: end_task
end_task:
Type: Task
Resource:
Fn::GetAtt: [end, Arn]
End: true
handler.tsにはこのように関数を並べます。
import { Handler } from 'aws-lambda';
import 'source-map-support/register';
// Map Stateになげるタスクを配列で返す
export const map: Handler = async () => {
return [1,2,3,4,5]
}
// Map Stateの処理。受け取った値 + 2倍にした数字をオブジェクトで返す
export const mapTask: Handler = async (event) => {
console.log(event)
return {
event,
times: event * 2
}
}
// 処理されたデータをログ+returnするだけの終端タスク
export const end: Handler = async (event) => {
console.log(JSON.stringify(event))
return {
statusCode: 200,
body: JSON.stringify(event)
};
}
出来上がったワークフローがこちら
これを実行すると、end_taskでは処理結果を配列で受け取っていることがわかります。
Input
[
{
"event": 1,
"times": 2
},
{
"event": 2,
"times": 4
},
{
"event": 3,
"times": 6
},
{
"event": 4,
"times": 8
},
{
"event": 5,
"times": 10
}
]
Output
{
"statusCode": 200,
"body": "[{\"event\":1,\"times\":2},{\"event\":2,\"times\":4},{\"event\":3,\"times\":6},{\"event\":4,\"times\":8},{\"event\":5,\"times\":10}]"
}
余談
State Machineの定義、ちょいちょいインデントミスとかするので不安な方はAWS CDKを検討してみてもよいかもしれません。
APIスタックの管理にServerless Frameworkを使っている + Lambda再利用したいなどの目的があるので会社ではこのプラグイン一択かなと思っていますが、気が向いたらそっちも紹介します。