本記事では、API GatewayからLambdaを非同期で呼び出す方法について紹介します。
バックエンド処理の完了を待たずに、利用者にレスポンスを返却したい。
バックエンド処理にはLambdaを利用しているがどうすればいんだろう??
と、思ってる方におすすめです。
この記事では、以下のことを紹介してます。
- APIGatewayからLambdaを非同期呼び出する設定方法
Lambdaの利用時、APIGatewayと合わせて使うのが一般的です。
しかし、APIGatewayは29秒でタイムアウトとなる制約があります。そのため、重たい処理をLambdaで行うと処理完了前にタイムアウトとなります。この事象を回避するためLambdaを非同期呼び出しにして検証した内容を具体的に紹介します。
なお、APIGatewayのタイムアウト対策として、StepFunctionsを利用して対応する方法もあります。こちらも内部的に非同期でLambda呼び出しが行われる方法となります。
ただしStepFunctionsでは、送信するペイロードのサイズが256KBまでしかできない制限があり、私の実現したい要件を達成できなかったので、当記事の内容を検証しました。
StepFunctionsを使って、Lambda呼び出しを非同期にする方法については、以下記事を参照ください。
API GatewayからLambda呼び出しを非同期にする設定
以下二つの設定が必要となります。
- リクエストヘッダーの設定
「X-Amz-Invocation-Type」に「’Event’」を設定 - Lambdaプロキシ統合をオフに設定
API Gatewayのリソースの設定
まずは、API GatewayからLambdaの非同期呼び出し検証用に、以下設定でAPI Gatewayのリソースを作成します。
注目すべき点は、Lambdaプロキシ統合をオフにしているところです。
作成後、統合リクエストの設定を変更していきます。
変更箇所はURLリクエストヘッダーのパラメータ部分となります。(Lambdaプロキシ統合をオンにしている場合だと、変更することができません。)
変更前は画像のように何も設定されていない状態です。
非同期として呼び出すにはリクエストヘッダーのパラメータを以下のように設定します。
パラメータに「X-Amz-Invocation-Type」を追加し、マッピング元に「’Event’」を設定します。
この設定を行うことで、クライアントからの呼び出しは全て非同期で呼び出されるようになります。
この設定により、このリソースはLambdaをキックするだけの処理となるので、ラムダの結果を受け取る場合は、処理結果を取得する別Lambdaを作成する必要があります。
非同期にするにあたり、対象のLambdaに処理状況をDynamoDBなどに登録する処理を追加し、対象データの処理状況を見るような処理結果を取得するLambdaを新規に作成するなど、アプリケーションとしての設計が必要となります。
注意点
上記の設定で、Lambda呼び出しを非同期にすることができました。
が、思わぬ落とし穴がありました。
それは、StepFunctionsと同様に256KBまでのペイロードのサイズ制限があることです。
試しに256KB以上のペイロードを設定しじっこうすると、ValidationErrorが返却されました。同期処理の際には、このような制限がなかったことから、AWSではStepFunctionsも含め非同期処理の場合は、ペイロードに256KB制限がありそうです。
本記事の内容でも、私がやりたかったことできなかったことを実現できなかったので、恒久的な対応として同期処理に戻し、タイムアウトエラーが返却された場合にはクライアント側でエラーとせず、後続の処理結果確認を行うLambdaから返却された値で処理結果を判断することとしました。
この方法だと、API Gatewayのログには504エラーが出力されてしまいますが、アプリケーションの実害はないのでよしとしました。
まとめ
APIGatewayからLambdaを非同期呼び出しする方法のまとめ
本記事では、API Gatewayから非同期でLambda呼び出しを行う具体的な方法を紹介しました。
StepFunctionsの非同期処理の対応と同様に、当記事で検証した方法でも私が実現したい要件を達成することはできませんでしたが、AWSのペイロードの制限の傾向がわかりましたので、別案で対応する決心がつきました。
本記事が皆様の参考となりましたら幸いです。
参考サイト
今回の対応をするにあたり、以下のサイトを参考にさせていただきました。
ありがとうございます。
コメント