AWS Lambdaプロキシ統合の利用有無による入出力の違いについて (Amazon API Gateway + AWS Lambda)

本記事は 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 Gateway での Lambda プロキシ統合 - Amazon API Gateway
API Gateway で Lambda プロキシ統合リクエストと統合レスポンスを設定する方法を学びます。

下記は先ほどのAPIを実行した際に、Lambdaに渡されたeventをそのまま出力したログです。(一部情報はマスクしております。)

形式的にも、先ほどのAWSのドキュメントに記載のものと同様だとわかります。

出力:statusCodeとbodyはマスト!構造的な出力が必要!

先ほどのLambdaの返却値には、statusCodeとbodyを含めていました。

この2つはLambdaプロキシ統合を使った際には必ず必要な情報です。

Lambdaプロキシ統合を使った際の返却値は、構造化された状態にする必要があります。

詳しくは下記のドキュメントをご参照ください。

API Gateway での Lambda プロキシ統合 - Amazon API Gateway
API Gateway で 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に関するリクエスト情報がほぼそのままに渡されるようなテンプレートです。

テンプレート本文は下記のようなイメージです。この状態で保存します。

なお、マッピングテンプレートに用いることができる情報などは下記ドキュメントに記載されています。

Amazon API Gateway API リクエストおよびレスポンスデータマッピングリファレンス - Amazon API Gateway
Amazon API Gateway で API メソッドリクエストからメソッドレスポンスパラメータへのデータマッピングを設定する

それでは、実際にテストしてみたいと思います。

今回のLambdaのソースコードはこのような感じで、ステータスコードと入力値である「event」をそのまま返します。

なお、あえてステータスコードは定義しません。

import json

def lambda_handler(event, context):

  print(event)

  return {

   'body': json.dumps(event)

  }

前の例と同じく「test」と入力し、挙動を確認します。

下記の結果が出ました。(一部情報はマスクしております。)

マッピングテンプレートで記載した通りの構文が入力値として渡されているのがわかります。
パスパラメータを取得したい場合は、赤枠で囲った部分である「params」→「path」→「input」から情報を取得するようなコードを書くと良いかと思います。

マッピングテンプレートを定義しなかったらどうなるか?

もしマッピングテンプレートを定義しなかったら、返却値は下記になります。(なお、入力値は同じくtestという文字列です。)
bodyの部分は空辞書が返却されています。
今回のLambdaは、受け取った内容をそのまま返却するというソースコードなので、空辞書が渡されているのがわかります。
もしAPI構築中にこのような辞書に見舞われたら、マッピングテンプレートが定義できていないのだと考えてください。

出力:Lambdaの返却値そのままに返却される。

先ほどの入力の例でもすでにお見せしてますが、Lambdaで定義した返却値がそのままに返却されています。

return {

  'body': json.dumps(event)

}

上記のような返却値だったため、実際のAPIの結果もbodyで始まり、入力値の内容がが返却されました。

Lambdaプロキシ統合の時と違い、ステータスコードなどの情報がなくてもエラーにはならず、ステータス200として返却されます。

返却値が自由に設定できるという意味では柔軟性は高いということがわかります。

まとめ

今回は、API GatewayのLambdaプロキシ統合がどのような入出力の違いを生むかを解説しました。

個人的な所感としては、Lambdaプロキシ統合は入出力の型が決まっているので、それについて考えずにAPI構築に集中できるため、基本的に使った方が開発生産性は上がると考えております。

逆にLambdaプロキシ統合を使わないケースとしては、入出力を完全にコントロールしたい場合が該当するのではないでしょうか。ただ、マッピングテンプレートの例を見てもらうとわかる通り、for分やif文などがあるため、場合によってはテストケースを作成してロジックが正しいか確認する必要もあることは念頭においた方が良いと考えます。

このブログが、皆さんのAPI Gateway開発の何かに役立てば幸いです。

著者について

フロントエンドもバックエンドも両方少しずつ勉強して、フルスタックエンジニアを目指してます。
サーバレス開発の楽しさを実感中!

ANGEL Dojo 2021 ANGEL賞、ベストアーキテクチャ賞ダブル受賞
2023 Japan AWS Jr. Champions
2022〜24 Japan AWS All Certifications Engineers

齋藤友宏をフォローする

クラウドに強いによるエンジニアブログです。

SCSKクラウドサービス(AWS)は、企業価値の向上につながるAWS 導入を全面支援するオールインワンサービスです。AWS最上位パートナーとして、多種多様な業界のシステム構築実績を持つSCSKが、お客様のDX推進を強力にサポートします。

AWSアプリケーション開発クラウドソリューション
シェアする
タイトルとURLをコピーしました