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再利用したいなどの目的があるので会社ではこのプラグイン一択かなと思っていますが、気が向いたらそっちも紹介します。

    広告ここから
    広告ここまで
    Home
    Search
    Bookmark