- 03-5820-1777平日10:00〜18:00
- お問い合わせ
今回はStep Functionsで作成したステートマシンをApi Gatewayから呼んで、レスポンスをJSON形式で受け取るという機能を実現してみたいと思います。
これが出来れば、Webの画面との連携も可能になるので選択肢が広まると思います。
今回は簡単なジャンケンのステートマシンを作成します。

タイプを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関数を作成します。
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を作成し各種設定して実行してみたいと思います。
ステートマシンを呼ぶ為のロールを作成します。
ここで作成したロールはPOSTメソッド作成で使用します。
次のポリシーをアタッチしたロールを作成して下さい。
今回はREST APIで作成しようと思います。

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

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


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


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を呼び出すなどをすれば良いと思います。