本記事は TechHarmony Advent Calendar 2024 12/17付の記事です。 |
どうもSCSK齋藤です。
今回は Amazon API Gateway と AWS Lambda を結びつけた際の、Lambdaプロキシ統合の利用有無によって変わる入出力の違いを書いていきたいと思います。
なお、本ブログで解説するAPI Gatewayは、「input」というパスパラメータでAPIに情報を連携し、Lambda側でステータスコードと一緒にパスパラメータの値をそのまま返却するものを例とします。
プロキシ統合ありの場合
まず、以下にプロキシ統合の場合のLambdaのソースコードを記します。
import json def lambda_handler(event, context): print(event) return { 'statusCode': 200, 'body': json.dumps(event['pathParameters']['input']) }
次にプロキシ統合の場合で、上記Lambdaが動いた場合の、APIの入出力結果を見てみたいと思います。
まずは、パスパラメータ(input)に渡す入力値です。
出力結果は下記の通りです。
入出力についてそれぞれポイントを記載します。
入力:eventの中身の構造に注意する!
重要なのは、「json.dumps(event[‘pathParameters’][‘input’])」の部分です。
Lambdaの入力値であるeventから、その配下の辞書形式でpathParametersという辞書のキーを取得しております。さらにその配下に今回のパスパラメータである「input」の情報を取得しております。
Lambdaプロキシ統合の場合、eventに渡されるデータ形式は決まっているため、その形式から必要なデータを取得してLambda関数で処理する必要があります。
AWSのドキュメントにて、データ形式は公開されておりますので、下記を参照してみると良いと思います。
下記は先ほどのAPIを実行した際に、Lambdaに渡されたeventをそのまま出力したログです。(一部情報はマスクしております。)
形式的にも、先ほどのAWSのドキュメントに記載のものと同様だとわかります。
出力:statusCodeとbodyはマスト!構造的な出力が必要!
先ほどのLambdaの返却値には、statusCodeとbodyを含めていました。
この2つはLambdaプロキシ統合を使った際には必ず必要な情報です。
Lambdaプロキシ統合を使った際の返却値は、構造化された状態にする必要があります。
詳しくは下記のドキュメントをご参照ください。
試しに、必要な構造化がされていない返却値を設定したらどうなるでしょうか?
下記Lambdaで試してみたいと思います。
import json def lambda_handler(event, context): print(event) return json.dumps(event['pathParameters']['input']
入力値は先ほどと同じでtestとしてみましたが、下記のエラーがAPIで出ました。
なお、Lambdaのログを見ても、エラーは出ておりません。
これはLambdaが正しく処理しているにも関わらず、構造化された返却値になっていない影響でAPIGateway側で発生したエラーとなります。
Lambdaプロキシ統合を使う際は、返却値は必ず構造化されたものを返却するようにしましょう!
プロキシ統合なしの場合
入力:マッピングテンプレートを定義する!
プロキシ統合なしの場合、何もせずにいるとAPIGateway→Lambdaに情報は適切に渡されません。
必ずマッピングテンプレートを定義する必要があります。
マッピングテンプレートは、APIの統合リクエストを編集する画面で設定できます。
どのような形式でLambdaに渡すかのテンプレートを定義することができます。今回は、標準で用意してある「メソッドリクエストのパススルー」を選択したいと思います。これは、APIに関するリクエスト情報がほぼそのままに渡されるようなテンプレートです。
テンプレート本文は下記のようなイメージです。この状態で保存します。
なお、マッピングテンプレートに用いることができる情報などは下記ドキュメントに記載されています。
それでは、実際にテストしてみたいと思います。
今回のLambdaのソースコードはこのような感じで、ステータスコードと入力値である「event」をそのまま返します。
なお、あえてステータスコードは定義しません。
import json def lambda_handler(event, context): print(event) return { 'body': json.dumps(event) }
前の例と同じく「test」と入力し、挙動を確認します。
マッピングテンプレートを定義しなかったらどうなるか?
出力:Lambdaの返却値そのままに返却される。
先ほどの入力の例でもすでにお見せしてますが、Lambdaで定義した返却値がそのままに返却されています。
return { 'body': json.dumps(event) }
上記のような返却値だったため、実際のAPIの結果もbodyで始まり、入力値の内容がが返却されました。
Lambdaプロキシ統合の時と違い、ステータスコードなどの情報がなくてもエラーにはならず、ステータス200として返却されます。
返却値が自由に設定できるという意味では柔軟性は高いということがわかります。
まとめ
今回は、API GatewayのLambdaプロキシ統合がどのような入出力の違いを生むかを解説しました。
個人的な所感としては、Lambdaプロキシ統合は入出力の型が決まっているので、それについて考えずにAPI構築に集中できるため、基本的に使った方が開発生産性は上がると考えております。
逆にLambdaプロキシ統合を使わないケースとしては、入出力を完全にコントロールしたい場合が該当するのではないでしょうか。ただ、マッピングテンプレートの例を見てもらうとわかる通り、for分やif文などがあるため、場合によってはテストケースを作成してロジックが正しいか確認する必要もあることは念頭においた方が良いと考えます。
このブログが、皆さんのAPI Gateway開発の何かに役立てば幸いです。