AWS Lambda(C#)でAPI Gatewayからパラメータを受け取る方法~Lambdaプロキシ統合編~

はじめに

前回、AWS Lambda(C#)でAPI Gatewayからパラメータを受け取る方法をご紹介しました。こちらです。

今回は「Lambdaプロキシ統合」を使用した方法をご紹介したいと思います。

Lambdaプロキシ統合とは

Amazon API Gateway Lambda プロキシ統合は、単一の API メソッドのセットアップで API を構築するシンプル、強力、高速なメカニズムです。Lambda プロキシ統合は、クライアントが単一の Lambda 関数をバックエンドで呼び出すことを可能にします。この関数は、他の AWS 関数の呼び出しを含め、他の Lambda サービスのさまざまなリソースや機能にアクセスします。

Lambda プロキシ統合では、クライアントが API リクエストを送信すると、API Gateway は、統合された Lambda 関数に raw リクエストをそのまま渡します。ただし、リクエストパラメータの順序は保持されません。このリクエストデータには、リクエストヘッダー、クエリ文字列パラメータ、URL パス変数、ペイロード、および API 設定データが含まれます。設定データには、現在のデプロイステージ名、ステージ変数、ユーザー ID、または承認コンテキスト (存在する場合) を含めることができます。バックエンド Lambda 関数では、受信リクエストデータを解析して、返すレスポンスを決定します。API Gateway が Lambda 出力を API レスポンスとしてクライアントに渡すには、Lambda 関数は結果をこの形式で返す必要があります。

Amazon API Gateway 開発者ガイドより引用

つまり、API Gatewayから決められたフォーマットでリクエストデータを受け取り、必要な処理をしたのち、決められたフォーマットでレスポンスデータを返すような流れになります。

C#のLambda関数においては、「決められたフォーマット」に沿った形でやりとりするために、「Amazon.Lambda.APIGatewayEvents」というパッケージにて、「APIGatewayProxyRequest」クラス、「APIGatewayProxyResponse」クラスが提供されているようです。Nugetから入手できます。

自作のクラスでも対応できましたが、今回はこちらを使った方法をご紹介したいと思います。

実装サンプル

API Gatewayから受け取ったパラメータを一式JSONデータで返すLambda関数のサンプルです。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

using Amazon.Lambda.Core;

using Amazon.Lambda.APIGatewayEvents;
using System.Text.Json;

// Assembly attribute to enable the Lambda function's JSON input to be converted into a .NET class.
[assembly: LambdaSerializer(typeof(Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer))]

namespace AWSLambda4
{
    public class Function
    {
        public APIGatewayProxyResponse FunctionHandler(APIGatewayProxyRequest input, ILambdaContext context)
        {
            var myHeaders = new Dictionary<string, string>();
            myHeaders.Add("Content-Type", "application/json");

            var response = new APIGatewayProxyResponse
            {
                StatusCode = 200
             ,
                Body = JsonSerializer.Serialize(input,typeof(APIGatewayProxyRequest),new JsonSerializerOptions{WriteIndented = true})
             ,
                IsBase64Encoded = false
             ,
                Headers = myHeaders
            };

            return response;
        }
    }
}

こちらAWSへパブリッシュします。次にAPI Gatewayを作成します。

「トリガーを追加」をクリックし、「REST API」を選択します。

既定では「Lambdaプロキシ統合の使用」にチェックが入っていると思います。もしチェックが入っていなければ入れてください。

下記のURLに対してGETリクエストを投げてみます。xxxxxxxxxx部は実際の環境へ置き換えてください。

https://xxxxxxxxxx.execute-api.ap-northeast-1.amazonaws.com/default/AWSLambda4?param1=value1¶m2=value2

うまくいくと下記のようなJSONデータが返ってきます。各種リクエストデータがLambda関数側へ渡されていることが確認できるかと思います。

{
  "Resource": "/AWSLambda4",
  "Path": "/AWSLambda4",
  "HttpMethod": "GET",
  "Headers": {
    "accept": "text/html,application/xhtml\u002Bxml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9",
    "accept-encoding": "gzip, deflate, br",
    "accept-language": "ja",
    "Host": "xxxxxxxxxx.execute-api.ap-northeast-1.amazonaws.com",
    "sec-fetch-dest": "document",
    "sec-fetch-mode": "navigate",
    "sec-fetch-site": "none",
    "sec-fetch-user": "?1",
    "upgrade-insecure-requests": "1",
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36",
    "X-Amzn-Trace-Id": "Root=1-xxxxxxxx-xxxxxxxxxxxxxxxxxxxxxxxx",
    "X-Forwarded-For": "xxx.xxx.xxx.xxx",
    "X-Forwarded-Port": "443",
    "X-Forwarded-Proto": "https"
  },
  "MultiValueHeaders": {
    "accept": [
      "text/html,application/xhtml\u002Bxml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9"
    ],
    "accept-encoding": [
      "gzip, deflate, br"
    ],
    "accept-language": [
      "ja"
    ],
    "Host": [
      "xxxxxxxxxx.execute-api.ap-northeast-1.amazonaws.com"
    ],
    "sec-fetch-dest": [
      "document"
    ],
    "sec-fetch-mode": [
      "navigate"
    ],
    "sec-fetch-site": [
      "none"
    ],
    "sec-fetch-user": [
      "?1"
    ],
    "upgrade-insecure-requests": [
      "1"
    ],
    "User-Agent": [
      "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36"
    ],
    "X-Amzn-Trace-Id": [
      "Root=1-xxxxxxxx-xxxxxxxxxxxxxxxxxxxxxxxx"
    ],
    "X-Forwarded-For": [
      "x"
    ],
    "X-Forwarded-Port": [
      "443"
    ],
    "X-Forwarded-Proto": [
      "https"
    ]
  },
  "QueryStringParameters": {
    "param1": "value1",
    "param2": "value2"
  },
  "MultiValueQueryStringParameters": {
    "param1": [
      "value1"
    ],
    "param2": [
      "value2"
    ]
  },
  "PathParameters": null,
  "StageVariables": null,
  "RequestContext": {
    "Path": "/default/AWSLambda4",
    "AccountId": "xxxxxxxxxxxx",
    "ResourceId": "dfnnaw",
    "Stage": "default",
    "RequestId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
    "Identity": {
      "CognitoIdentityPoolId": null,
      "AccountId": null,
      "CognitoIdentityId": null,
      "Caller": null,
      "ApiKey": null,
      "ApiKeyId": null,
      "AccessKey": null,
      "SourceIp": "xxx.xxx.xxx.xxx",
      "CognitoAuthenticationType": null,
      "CognitoAuthenticationProvider": null,
      "UserArn": null,
      "UserAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36",
      "User": null,
      "ClientCert": null
    },
    "ResourcePath": "/AWSLambda4",
    "HttpMethod": "GET",
    "ApiId": "xxxxxxxx",
    "ExtendedRequestId": "xxxxxxxxxxxxxxx=",
    "ConnectionId": null,
    "ConnectionAt": 0,
    "DomainName": "xxxxxxxxxx.execute-api.ap-northeast-1.amazonaws.com",
    "DomainPrefix": "xxxxxxxxxx",
    "EventType": null,
    "MessageId": null,
    "RouteKey": null,
    "Authorizer": null,
    "OperationName": null,
    "Error": null,
    "IntegrationLatency": null,
    "MessageDirection": null,
    "RequestTime": "16/Oct/2020:02:17:48 \u002B0000",
    "RequestTimeEpoch": 1602814668382,
    "Status": null
  },
  "Body": null,
  "IsBase64Encoded": false
}

以上です。

参考

API Gateway で Lambda プロキシ統合をセットアップする

.NET での JSON のシリアル化と逆シリアル化 (マーシャリングとマーシャリング解除) – 概要