記事を書いたきっかけ
人に教えることが増えてきたので、説明用にまとめてみました。
「間の部分がわからない」という質問をよく受けるのですが、結局API Gatewayのことですね、ってパターンが多いのでこのようなタイトルにしました。
API Gatewayの初級~中級レベルの解説記事です。
私自身もまだまだ学習中の身ですので、誤りや誤解を生むような表現があったらご教示ください。
API Gateway → Lambdaの全体像を図解してみた
図解するとこんな感じになるという認識です。
例えば
https://APIのドメイン/dev/index/必要なパラメータ
というパスを叩くと
このようになります。
それぞれの概念をざっくり理解する
API Gatewayの概念
ステージ
ステージとは「本番」「開発」「テスト」といったAPIの公開先や実行環境の区切りのことを言います。
実際のURIではドメインの次に来る部分です。(マッピングの設定によってはステージを非表示にすることもできます)
https://example-api.amazonaws.com/dev/index
https://example-api.amazonaws.com/prd/index
これで異なる環境のAPIを叩くことができます。
リソース
リソースとはAPIで公開する機能やエンドポイントのパス単位です。
/index → トップページデータ取得
/detail → 詳細データ取得
RESTのROAでいうリソースに近い概念という認識です。API Gateway上ではパス構造を表す設定項目として扱われます。
メソッド
メソッドとはリソースに対してどんな操作をするか(GET/POST/PUT/DELETEなど)です。
HTTPメソッドだと捉えています。以下とても良い記事で勉強になりました。
メソッドには4つの構成要素があり、それらがメソッドリクエスト、統合リクエスト、統合レスポンス、メソッドレスポンスとなります(非プロキシ統合の場合、後述)
非プロキシ統合の場合
それぞれについて解説します。
1. メソッドリクエスト
端的に言うと、
クライアントからのリクエストをAPI Gatewayとしてどう受け付けるかの定義
を担います。
クライアントからAPIにリクエストが届いた時点で行われる処理です。
入力のバリデーションや認証認可の役割を担います。
具体的には、認可、APIキーの要否、URLパス・クエリ文字列・ヘッダーなどのリクエストパラメータ、必要に応じてリクエストモデルによる検証を設定します。
2. 統合リクエスト
端的に言うと、
APIからバックエンド(今回の場合でいうとLambda)とのマッピング
を担当します。
統合タイプから、Lambdaなのか他のAWSサービス(StepFunctionsなど)なのかを選択して統合します。
2つ目の役割としてリクエストの変換などを行います。
個人的には入力データをJSONに整形してLambdaに渡す場合が多いです。
具体例として、
POSTでアイテムの情報を受け取る時、元々の受け取ったリクエストが
/items?id=abc123&value=42
のような場合の時に非プロキシ統合では、Lambda側で扱いやすい形式にしたい場合、統合リクエストのマッピングテンプレートでクエリ文字列やパスパラメータをJSONに整形して渡すことができます。
{"id": "abc123", "value": 42}
のように変換してくれるって感じです。
また、統合リクエストでLambdaのエイリアスの指定を行うことができます。
上記の画像でもdevエイリアスを指定しています。
arn:aws:lambda:{region}:{account_id}:function:{function_name}:{alias_name}
このように指定した関数の後ろに:{alias}のように追記するとことで、指定したエイリアスにリクエストを当てることができるようになります。

3. 統合レスポンス
バックエンドからのレスポンスを受け取って、APIで加工する役割を担っています。
- ステータスコードマッピング(200 / 400 / 500など)
- バックエンドのレスポンスをクライアント用に整形
- レスポンスヘッダーの中身の定義(値の設定)
などを設定するのはこの部分です。
個人的には一番ピンときにくい概念でした。
APIを作成する際に基本的には以下のような形式で作成すると思います。
{
"statusCode": 200,
"headers": {
"Content-Type": "application/json"
},
"body": "{\"message\":\"hello\",\"userId\":123}"
}
しかし、Lambdaではできるだけ簡略化したレスポンスを作成して、整形の部分はAPI Gatewayに持たせたい場合などでは、
{
"message": "hello",
"userId": 123
}
このように定義し、statusCodeや、headersを含ませないことが可能です。このような場合に使用するのが統合レスポンスという概念です。
ですので、自分でstatusCodeを定義する場合にはあまり必要のない処理であり、Lambda側で statusCode や headers を含むHTTPレスポンス形式を組み立てたい場合は、プロキシ統合を使うと設定をシンプルにできます(後述)
4. メソッドレスポンス
これは処理というよりもただの宣言です。
端的に言うと、
クライアントに返す可能性のあるHTTPステータスコード、ヘッダー、レスポンスモデルを宣言する部分
と言えます。
具体的には
- 返すヘッダーの種類を定義
- レスポンスモデル(JSONスキーマ)
などを宣言しています。
実際の値の設定や変換は統合レスポンス側で行い、統合レスポンスは対応するメソッドレスポンスへ結果をマッピングします。
プロキシ統合の場合
これまでの説明内容を全てAPI Gateway側で設定するのはなかなか大変です。
それを省略する手段としてプロキシ統合というものが用意されています。
ざっくりこのようにイメージしています。先ほどまでの非プロキシ統合と比較するとレスポンスへの処理がほとんど簡略化されていることがわかります。
Lambdaプロキシ統合は、API GatewayがリクエストをイベントオブジェクトとしてLambdaに渡し、LambdaのレスポンスをHTTPレスポンスとしてクライアントへ返す仕組みです。
そのため、非プロキシ統合のような細かいマッピング設定を減らせます。
しかし素通りさせる分、Lambda側ではレスポンスには一定のルールに従ったレスポンス形式で返す必要があります。
例えば正常レスポンスであるなら、以下の形を遵守する必要があります。bodyが文字列指定であることが特徴的かなと思ってます。
{
"statusCode": 200,
"headers": {
"Content-Type": "application/json"
},
"body": "{\"message\":\"hello\"}"
}
異常系
{
"statusCode": 400,
"headers": {
"Content-Type": "application/json"
},
"body": "{\"message\":\"bad request\"}"
}
つまり、プロキシ統合では、非プロキシ統合で行なっていたレスポンスのマッピング処理を簡略化できる代わりにLambda側でレスポンス形式を組み立てる必要があります。
詳細はドキュメントをご確認ください。
まとめ
以上のような流れで、API Gateway → Lambdaまでの通信が可能となります。
API Gatewayは一見わかりにくいですが、リクエストを受け付ける部分、バックエンドへ渡す部分、レスポンスを整形する部分に分けて考えると理解しやすくなると思います。
基本的にLambdaとの連携の際は、プロキシ統合を使ってLambda側で制御することが多いのかなと考えていますが、非プロキシ統合についてもある程度把握しておくことも大切なのかなと考えています。
最後まで読んでいただきありがとうございました。















