⏰
API Gatewayのタイムアウトに対処する
やりたかったこと
- APIGatewayとLambdaを用いてエンドポイントを叩いた際にLambda関数を実行し画像処理を行い,レスポンスを返したかった
- しかし、Lambdaのタイムアウト設定が3s~900s(15m)で設定できるのに対してAPIGatewayのタイムアウトは最大で29sまでしか設定できない。
- 画像のサイズが大きくなってくるとAPIGatewayがタイムアウトしてしまうという問題に直面していた。
- そこでStep Functionsを組み合わせることで先にレスポンスを返し、裏ではLambdaが処理を実行し続けるような非同期の形にする方針をとった。
構築方法は以下を参考にして実装しました
API Gatewayのテストメソッドを使用して、実行テストを行いました。
以下のパラメータを指定します。
{
"stateMachineArn": "arn:aws:states:us-west-2:123456789:stateMachine:test”,
"input": "{ \”name\”: \"$input.params(‘name’)\”, \"body\": $util.escapeJavaScript($input.body) }"
}
また、Goで実装したため、関数ハンドラは以下を参考にして実装しました。
package main
import (
"context"
"fmt"
"github.com/aws/aws-lambda-go/lambda"
)
type MyEvent struct {
Name string `json:"name"`
}
func HandleRequest(ctx context.Context, event *MyEvent) (*string, error) {
if event == nil {
return nil, fmt.Errorf("received nil event")
}
message := fmt.Sprintf("Hello %s!", event.Name)
return &message, nil
}
func main() {
lambda.Start(HandleRequest)
}
このように実装し、APIGatewayでテストをすると、Step Functionsが動くことが確認できると思います。
Lambda関数が実行され、成功すると、レスポンスが返ってくるのが確認できると思います。
しかし、この後にも問題が発生しました。Step Functionsのデータサイズ上限は256KBなので、大きな画像データを返すことができなかったのです。
The state/task 'lambda' returned a result with a size exceeding the maximum number of bytes service limit.
どのように対処したかというと、s3にデータを格納し、そのurlを返す、という実装に変更しました。Go側でAWSSDK経由でs3にアップロード、取得を行い、そのurlを返すことで画像を返すことに成功しました。
Discussion