

API GatewayのGETメソッド、bodyの挙動は統合タイプで変わる
この記事は、構成と文章の整理にAIを使っています。
あくまで読みやすくするための補助で、内容そのものをAIにすべて任せて書いているわけではありませんが、ところどころ相談しながら整えています。
結論
API GatewayのGETメソッドでbodyを送った場合の挙動は、統合タイプで完全に分かれる。
- Lambdaプロキシ統合: bodyはそのままLambdaの
event.bodyに渡る - HTTP統合・VPC Link統合(非プロキシ): Integration Requestのメソッドをリソースメソッドと同じGETのままにしていると、bodyはAPI Gatewayの時点でドロップされ、バックエンドには空のペイロードしか届かない
「GETにbodyを付けたら無視されることがある」くらいのふわっとした理解だと、Lambda統合で普通に動いてしまって気づかないパターンと、HTTP/VPC Link統合で無言でデータが消えるパターンの両方を踏み抜く。
仕様上の位置づけ
API Gatewayの公式ドキュメントでは、method requestのpayload設定はPOST・PUT・PATCHのケースとして説明されていて、GETはそもそも対象に入っていない。つまりGETでbodyを使うこと自体、公式に想定された使い方ではない。
HTTP/1.1の仕様自体はGETリクエストのbodyを明示的に禁止しているわけではないけど、意味的な扱いが定義されていないので、多くのHTTPクライアント・サーバー・プロキシで想定通りに扱われる保証がない。
統合タイプ別の挙動
Lambdaプロキシ統合
GETでもbodyはそのままLambda関数に渡る。event.body に入ってくるので、実装上は「GETなのにbodyを読める」状態になる。動くには動くが、REST的な意味論からは外れた使い方になる。
HTTP統合・VPC Link統合(非プロキシ)
Integration Requestのメソッドがリソースメソッドと同じGETのままだと、bodyはAPI Gatewayの時点でドロップされる。バックエンドには空のペイロードしか届かない。
bodyを通したい場合は、リソースメソッド自体はGETのままにしつつ、Integration RequestのメソッドだけをPOSTに変更する、という回避策がある。ただしこれは実質「GETの皮を被ったPOST」を作っているだけなので、素直にリソースメソッド自体をPOSTにした方が分かりやすい場面が多い。
対処法
複雑なデータや多めの情報を渡したいなら、素直にPOSTかPUTを使うのが一番安全。API Gatewayのpayload設定周りも、この2つ(とPATCH)を前提に作られている。
GETでどうしても情報を渡したいなら、クエリパラメータかパスパラメータに寄せる。API Gatewayのmethod request側で普通に設定できるし、キャッシュやロギング、途中に挟まるプロキシでの扱いも安定してる。
未確認
Lambda以外のAWSサービス統合(DynamoDBやS3への直接統合など)でGET+bodyがどう扱われるかは、今回確認してない。統合タイプごとに個別に見た方が良さそう。