コラム

[AWS]Step FunctionsのステートマシンをApi Gatewayから同期起動(Express)

今回はStep Functionsで作成したステートマシンをApi Gatewayから呼んで、レスポンスをJSON形式で受け取るという機能を実現してみたいと思います。
これが出来れば、Webの画面との連携も可能になるので選択肢が広まると思います。

目次

ステートマシン作成

今回は簡単なジャンケンのステートマシンを作成します。

  • 0~2の値を渡します。
  • 0はグー、1はチョキ、2はパーとします。
  • 0~2の値をランダムで作成し、入力値がその値に勝ったのかを判断し結果を出力します。

作成方法

タイプをExpressにすると同期実行が可能です。

ワークフロー作成

Worflow studioでのイメージ

ワークフロー定義

{
  "Comment": "A description of my state machine",
  "StartAt": "Lambda Invoke",
  "States": {
    "Lambda Invoke": {
      "Type": "Task",
      "Resource": "arn:aws:states:::lambda:invoke",
      "Parameters": {
        "FunctionName": "arn:aws:lambda:ap-northeast-1:XXXXXXX:function:RandomNumberSelection:$LATEST",
        "Payload": {
          "number.$": "$.number"
        }
      },
      "Retry": [
        {
          "ErrorEquals": [
            "Lambda.ServiceException",
            "Lambda.AWSLambdaException",
            "Lambda.SdkClientException",
            "Lambda.TooManyRequestsException"
          ],
          "IntervalSeconds": 2,
          "MaxAttempts": 6,
          "BackoffRate": 2
        }
      ],
      "Next": "Choice",
      "ResultPath": "$.Janken",
      "ResultSelector": {
        "result.$": "$.Payload.result"
      }
    },
    "Choice": {
      "Type": "Choice",
      "Choices": [
        {
          "And": [
            {
              "Variable": "$.Janken.result",
              "NumericEquals": 0
            },
            {
              "Variable": "$.number",
              "NumericEquals": 1
            }
          ],
          "Next": "Lose"
        },
        {
          "And": [
            {
              "Variable": "$.Janken.result",
              "NumericEquals": 1
            },
            {
              "Variable": "$.number",
              "NumericEquals": 2
            }
          ],
          "Next": "Lose"
        },
        {
          "Variable": "$.Janken.result",
          "NumericEqualsPath": "$.number",
          "Next": "Draw"
        }
      ],
      "Default": "Win"
    },
    "Lose": {
      "Type": "Pass",
      "End": true,
      "Result": {
        "result": "You Lose"
      }
    },
    "Win": {
      "Type": "Pass",
      "End": true,
      "Result": {
        "result": "You Won"
      }
    },
    "Draw": {
      "Type": "Pass",
      "End": true,
      "Result": {
        "result": "Draw"
      }
    }
  }
}

Lambda作成

ランダム値を出力するLambda関数を作成します。

import json
import random

def lambda_handler(event, context):
    # TODO implement
    num = random.randint(0,2)
    return {
        'result': num
    }

単体でステートマシンを実行

入力値

{
    "number": 1
}

チョキを出してみる。

実行結果

{
  "result": "You Lose"
}

今回は負けたみたいです。

Api Gatewayの設定

ではApi Gatewayを作成し各種設定して実行してみたいと思います。

ロール作成

ステートマシンを呼ぶ為のロールを作成します。
ここで作成したロールはPOSTメソッド作成で使用します。
次のポリシーをアタッチしたロールを作成して下さい。

  • AmazonAPIGatewayPushToCloudWatchLogs
  • AWSStepFunctionsFullAccess

Api作成

今回はREST APIで作成しようと思います。

「CallStateMachieTest」というAPI名にします。

リソース作成

次はリソースを作成します。今回は「callstatemachinetest」という名前にします。

メソッド作成

上記で作成したリソースにメソッドを作成します。JSONデータを渡すのでPOSTメソッドの作成をします。

  • 総合タイプ:AWSサービス指定
  • AWSリージョン:ステートマシンを作成したリージョン指定
  • AWSサービス:Step Functionsを選択
  • HTTPメソッド:POSTを選択
  • アクションの種類:アクション名の使用を選択
  • アクション:StartSyncExecutionを入力
  • 実行ロール:上記で作成したロールのarnを指定
  • コンテンツの処理:パススルーを選択
  • デフォルトタイムアウトの使用:今回はチェックする

取り合えず実行してみる

StepFunctionから返されるデータを取得するにはリクエスト、レスポンスのマッピングテンプレートに設定が必要です。
設定がない場合は、リクエストする際のデータとレスポンスで返ってくるデータが次の様なデータになります。
テストで実行してみましょう。

リクエスト本文に次の値を入れて実行します。

リクエスト本文

{
   "input": "{\"number\" : 1}",
   "stateMachineArn": "arn:aws:states:ap-northeast-1:XXXXXXXXXX:stateMachine:JankenStateMachine"
}

レスポンス本文


{"billingDetails":
	{"billedDurationInMilliseconds":100,"billedMemoryUsedInMB":64},
	"executionArn":"arn:aws:states:ap-northeast-1:XXXXXXXX:express:JankenStateMachine:dcedd369-48be-4d02-973b-20030df3e238:0dac9732-d879-4bdb-9200-9715c003de11",
	"input":"{\"number\" : 1}",
	"inputDetails":{"__type":"com.amazonaws.swf.base.model#CloudWatchEventsExecutionDataDetails","included":true},
	"name":"dcedd369-48be-4d02-973b-20030df3e238",
	"output":"{\"result\":\"You Lose\"}",
	"outputDetails":{"__type":"com.amazonaws.swf.base.model#CloudWatchEventsExecutionDataDetails","included":true},
	"startDate":1.672392698917E9,
	"stateMachineArn":"arn:aws:states:ap-northeast-1:XXXXXXXX:stateMachine:JankenStateMachine",
	"status":"SUCCEEDED","stopDate":1.672392699004E9,"traceHeader":"Root=1-63aeaffa-f7869e29d7a87d1ac0363f62;Sampled=1"
}

以上の様に色々な情報が返ってきます。
リクエストで送る情報、レスポンスで受け取る情報の簡素化を図るには以下で説明するリクエスト、レスポンスのマッピングテンプレートに設定が必要です。

リクエスト・レスポンス本文簡素化

リクエスト本文を簡素化

ステートマシン実行におけるリクエスト本文情報の簡素を図るにはリクエストのマッピングプレートに設定が必要です。

マッピングテンプレートの追加で「application/json」を追加し、内容に以下の情報を記述します。

#set($input = $input.json('$'))
{
   "input": "$util.escapeJavaScript($input)",
   "stateMachineArn": "arn:aws:states:ap-northeast-1:XXXXXXXXXXX:stateMachine:ステートマシン名"
}

レスポンス本文を簡素化

レスポンス本文情報の簡素を図るにはレスポンスのマッピングプレートに設定が必要です。

マッピングテンプレートの追加で「application/json」を追加し、内容に以下の情報を記述します。

#set ($parsedPayload = $util.parseJson($input.json('$.output')))
$parsedPayload

以上で設定は完了です。

再度実行

では再度実行してみます。

リクエスト本文

{
   "number" : 1
}

レスポンス本文

{"result":"You Won"}

簡素化されている事が確認出来ました。

以上でApi Gatewayからステートマシンの同期呼び出し方法の説明を終わります。
画面から呼びたい場合は、デプロイ後にVue.jsやReactなどからRestApiを呼び出すなどをすれば良いと思います。

この記事をシェアする
  • Facebookアイコン
  • Twitterアイコン
  • LINEアイコン

お問い合わせ ITに関するお悩み不安が少しでもありましたら、
ぜひお気軽にお問い合わせください

お客様のお悩みや不安、課題などを丁寧に、そして誠実にお伺いいたします。

お問い合わせはこちら
お電話でのお問い合わせ 03-5820-1777(平日10:00〜18:00)
よくあるご質問