0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

APIGatewayとStepFunctionでの非同期実行時に使えるマッピングテンプレートの工夫

Posted at

はじめに

APIGatewayには、最大29秒までの実行時間制限があります。しかし、意外と簡単にその制限を超えてしまうことがあります。
最近では、申請をすればこの制限を延ばせるようですが、そもそも長時間待たせる設計は良くないと考え、下記のように非同期実行に変更しました。

本題

StepFunctionとAPIGatewayの非同期実行については、多くの情報が既にあるのでここでは詳細は割愛します。
今回は私が実践したアプローチをご紹介します。

  1. APIGatewayからStepFunctionを非同期で実行します。この際、実行完了を待たずに、StepFunctionの実行ARNをすぐにレスポンスとして返します。
  2. そのARNを使って、StepFunctionの実行が完了しているかを確認します。

StepFunctionに渡すデータの形式は決まっており、以下のような形になります。

// リクエストのマッピングテンプレート
#set($input = $input.json('$'))
{
   "input": "$util.escapeJavaScript($input)",
   "stateMachineArn": "実行するStepFunctionのARN"
}

$input.jsonの内容をそのまま渡すだけなら簡単ですが、例えば、エンドポイントごとに固定の値を渡したい場合には少し手を加える必要があります。
私は以下のようにカスタマイズしました。

// 作成するデータ形式
{
    "request": {
        "headers": {値},
        "body": {値}
    }
}
// リクエストのマッピングテンプレート
#set($input = $input.json('$'))
{
    #set($inputJson = '{"request":{"headers":{')
    #foreach($headerName in $input.params().header.keySet())
        #set($headerValue = $input.params().header.get($headerName))
        #set($inputJson = $inputJson + '"' + $headerName + '":"' + $headerValue + '"')
       #if($foreach.hasNext)
          #set($inputJson = $inputJson + ',')
       #end
       // ここに追加すればheaderに追加可能
    #end
    
    #set($inputJson = $inputJson + '},"body":{')
    #foreach($item in $input.path('$').entrySet())
       #set($inputJson = $inputJson + '"' + $item.key + '":"' + $item.value + '"')
       #if($foreach.hasNext)
          #set($inputJson = $inputJson + ',')
       #end
       // ここに追加すればbodyに追加可能
    #end
    
    #set($inputJson = $inputJson + '}}}')
    {
       "input": "$util.escapeJavaScript($inputJson)",
       "stateMachineArn": "ステップファンクションの実行ARN"
    }
}

このテンプレートでやっていることはシンプルです。リクエストされたheaderbodyをループしてJSON形式の文字列を作成し、それをエスケープしてinputキーに入れています。
StepFunctionへのinputは文字列である必要があるため、このようにエスケープ処理を行っています。

さいごに

似たような処理を行っている方もいますが、多くの方はmapを作成後にreplaceで=:に変換していました。
(mapがkey=value形式で出力されるため、それをkey:valueのJSON形式に変換する方法です)

しかし、この方法では、リクエスト文字列に=が含まれている場合に意図しない変換が発生する可能性があります。
そのため、私はループを回して手動で文字列を作成する方法を選びました。

このアプローチにたどり着くまでに意外と苦労したため、メモとして残しておきます。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?