AWS Lambda を Amazon API Gateway に使用する - AWS Lambda

AWS Lambda を Amazon API Gateway に使用する

Amazon API Gateway を使用して、Lambda 関数の HTTP エンドポイントを持つウェブ API を作成できます。API Gateway は、HTTP リクエストを Lambda 関数にルーティングするウェブ API を作成および文書化するためのツールを提供します。認証および承認のコントロールにより、API へのアクセスを保護できます。API は、インターネット経由でトラフィックを処理することも、VPC 内でのみアクセス可能にすることもできます。

パブリックエンドポイントを Lambda 関数に追加するには

  1. Lambda コンソール (関数ページ) を開きます。

  2. 関数を選択します。

  3. [Designer] で、[Add trigger] を選択します。

  4. [API Gateway] を選択します。

  5. [API] で、[Create an API (API の作成)] を選択します。

  6. [Security (セキュリティ)] で、[Open (開く)] を選択します。

  7. [Add] を選択します。

デザイナーで [API Gateway] トリガーを選択した状態で、API Gateway で関数を呼び出すエンドポイントを選択します。


      Lambda 関数にアタッチされた API Gateway API エンドポイント。

API Gateway API は、ステージ、リソース、メソッド、および統合で構成されています。ステージとリソースによって、エンドポイントのパスが決まります。

API パス形式

  • /prod/prod ステージおよびルートリソース。

  • /prod/userprod ステージおよび user リソース。

  • /dev/{proxy+}dev ステージ内の任意のルート。

  • / – (HTTP API) デフォルトのステージおよびルートリソース。

Lambda 統合は、パスと HTTP メソッドの組み合わせを Lambda 関数にマッピングします。HTTP リクエストのボディをそのまま渡すように (カスタム統合)、またはヘッダー、リソース、パス、メソッドなどすべてのリクエスト情報を含むドキュメントにリクエストボディをカプセル化するように、API Gateway を設定できます。

Amazon API Gateway は、HTTP リクエストの JSON 表現を含むイベントを使用して、関数を同期的に呼び出します。カスタム統合の場合、イベントはリクエストのボディです。プロキシ統合の場合、イベントは定義された構造を持ちます。次の例は、API Gateway REST API からのプロキシイベントを示しています。

event.json API Gateway プロキシイベント (REST API)

{ "resource": "/", "path": "/", "httpMethod": "GET", "requestContext": { "resourcePath": "/", "httpMethod": "GET", "path": "/Prod/", ... }, "headers": { "accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9", "accept-encoding": "gzip, deflate, br", "Host": "70ixmpl4fl.execute-api.us-east-2.amazonaws.com", "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Safari/537.36", "X-Amzn-Trace-Id": "Root=1-5e66d96f-7491f09xmpl79d18acf3d050", ... }, "multiValueHeaders": { "accept": [ "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9" ], "accept-encoding": [ "gzip, deflate, br" ], ... }, "queryStringParameters": null, "multiValueQueryStringParameters": null, "pathParameters": null, "stageVariables": null, "body": null, "isBase64Encoded": false }

この例では、REST API の Prod ステージのルートパスへの GET リクエストのイベントを示します。イベントのシェイプと内容は、API タイプと設定によって異なります。

API Gateway は関数からのレスポンスを待ち、その結果を呼び出し元に中継します。カスタム統合の場合は、統合レスポンスとメソッドレスポンスを定義して、関数からの出力を HTTP レスポンスに変換します。プロキシ統合の場合、関数はレスポンスを特定の形式で表現して応答する必要があります。

次の例は、Node.js 関数からのレスポンスオブジェクトを示しています。レスポンスオブジェクトは、JSON ドキュメントを含む成功した HTTP レスポンスを表します。

index.js – プロキシ統合レスポンスオブジェクト (Node.js)

var response = { "statusCode": 200, "headers": { "Content-Type": "application/json" }, "isBase64Encoded": false, "multiValueHeaders": { "X-Custom-Header": ["My value", "My other value"], }, "body": "{\n \"TotalCodeSize\": 104330022,\n \"FunctionCount\": 26\n}" }

Lambda ランタイムは、レスポンスオブジェクトを JSON にシリアル化し、API に送信します。API はレスポンスを解析し、それを使用して HTTP レスポンスを作成します。次に、そのレスポンスを元のリクエストを実行したクライアントに送信します。

例 HTTP レスポンス

< HTTP/1.1 200 OK < Content-Type: application/json < Content-Length: 55 < Connection: keep-alive < x-amzn-RequestId: 32998fea-xmpl-4268-8c72-16138d629356 < X-Custom-Header: My value < X-Custom-Header: My other value < X-Amzn-Trace-Id: Root=1-5e6aa925-ccecxmplbae116148e52f036 < { "TotalCodeSize": 104330022, "FunctionCount": 26 }

API 内のリソースは、GET や POST などの 1 つ以上のメソッドを定義します。メソッドには、Lambda 関数または別の統合タイプにリクエストをルーティングする統合があります。各リソースとメソッドを個別に定義することも、特殊なリソースとメソッドタイプを使用して、パターンに一致するすべてのリクエストを照合することもできます。プロキシリソースは、リソースの下にあるすべてのパスをキャッチします。ANY メソッドは、すべての HTTP メソッドをキャッチします。

アクセス許可

Amazon API Gateway は、関数のリソースベースのポリシーから関数を呼び出すアクセス許可を取得します。API 全体に対する呼び出しアクセス許可を付与したり、ステージ、リソース、またはメソッドに対する制限付きアクセスを付与したりできます。

Lambda コンソールまたは API Gateway コンソールを使用するか、AWS SAM テンプレートで API を関数に追加すると、関数のリソースベースのポリシーが自動的に更新されます。次の例は、AWS SAM テンプレートによって追加されたステートメントを含む関数ポリシーを示しています。

例 関数ポリシー

{ "Version": "2012-10-17", "Id": "default", "Statement": [ { "Sid": "nodejs-apig-functiongetEndpointPermissionProd-BWDBXMPLXE2F", "Effect": "Allow", "Principal": { "Service": "apigateway.amazonaws.com" }, "Action": "lambda:InvokeFunction", "Resource": "arn:aws:lambda:us-east-2:123456789012:function:nodejs-apig-function-1G3MXMPLXVXYI", "Condition": { "ArnLike": { "AWS:SourceArn": "arn:aws:execute-api:us-east-2:123456789012:ktyvxmpls1/*/GET/" } } } ] }

Lambda コンソールの [アクセス許可] タブで関数ポリシーを確認します。

次の API オペレーションを使用して、関数ポリシーのアクセス許可を手動で管理できます。

既存の API への呼び出しアクセス許可を付与するには、add-permission コマンドを使用します。

$ aws lambda add-permission --function-name my-function \ --statement-id apigateway-get --action lambda:InvokeFunction \ --principal apigateway.amazonaws.com \ --source-arn "arn:aws:execute-api:us-east-2:123456789012:mnh1xmpli7/default/GET/" { "Statement": "{\"Sid\":\"apigateway-test-2\",\"Effect\":\"Allow\",\"Principal\":{\"Service\":\"apigateway.amazonaws.com\"},\"Action\":\"lambda:InvokeFunction\",\"Resource\":\"arn:aws:lambda:us-east-2:123456789012:function:my-function\",\"Condition\":{\"ArnLike\":{\"AWS:SourceArn\":\"arn:aws:execute-api:us-east-2:123456789012:mnh1xmpli7/default/GET\"}}}" }
注記

関数と API が異なるリージョンにある場合、ソース ARN のリージョン識別子は、API のリージョンではなく、関数のリージョンと一致している必要があります。API Gateway が関数を呼び出すと、API の ARN に基づくリソース ARN が使用されますが、その関数のリージョンと一致するように変更されます。

この例のソース ARN は、API のデフォルトステージにあるルートリソースの GET メソッドでの統合に ID mnh1xmpli7 のアクセス許可を付与します。ソース ARN でアスタリスクを使用すると、複数のステージ、メソッド、またはリソースにアクセス許可を付与できます。

リソースパターン

  • mnh1xmpli7/*/GET/* – すべてのステージのすべてのリソースの GET メソッド。

  • mnh1xmpli7/prod/ANY/userprod ステージの user リソースの ANY メソッド。

  • mnh1xmpli7/*/*/* – すべてのステージのすべてのリソースの任意のメソッド。

ポリシーの表示とステートメントの削除の詳細については、「リソースベースのポリシーのクリーンアップ」を参照してください。

API Gateway API でのエラーの処理

API Gateway は、すべての呼び出しエラーと関数エラーを内部エラーとして扱います。Lambda API が呼び出しリクエストを拒否した場合、API Gateway は 500 エラーコードを返します。関数が実行されてもエラーが返された場合、または誤った形式でレスポンスが返された場合、API Gateway は 502 を返します。どちらの場合も、API Gateway からのレスポンスの本文は {"message": "Internal server error"} です。

以下の例では、関数エラーになり API Gateway から 502 が返されたリクエストの X-Ray トレースマップを示しています。クライアントは一般的なエラーメッセージを受け取ります。


        API Gateway での関数エラーのトレースマップ。

エラーレスポンスをカスタマイズするには、コードでエラーをキャッチし、レスポンスを必要な形式に加工する必要があります。

index.js – エラーの形式加工

var formatError = function(error){ var response = { "statusCode": error.statusCode, "headers": { "Content-Type": "text/plain", "x-amzn-ErrorType": error.code }, "isBase64Encoded": false, "body": error.code + ": " + error.message } return response }

API Gateway は、このレスポンスをカスタムステータスコードと本文を含む HTTP エラーに変換します。トレースマップで、関数ノードが緑色なのは、エラーを処理したためです。


        API Gateway での形式加工されたエラーのトレースマップ。

API タイプの選択

API Gateway は、Lambda 関数を呼び出す 3 種類の API をサポートしています。

  • HTTP API – 軽量で低レイテンシーの RESTful API。

  • REST API – カスタマイズ可能で機能豊富な RESTful API。

  • WebSocket API – 全二重通信のためにクライアントとの永続的な接続を維持するウェブ API。

HTTP API と REST API は、両方とも HTTP リクエストを処理し、レスポンスを返す RESTful API です。HTTP API は新しいバージョンであり、API Gateway バージョン 2 API を使用して構築されています。HTTP API では、次の機能が新しく追加されました。

HTTP API の機能

  • 自動デプロイ – ルートまたは統合を変更した場合、変更は自動デプロイが有効になっているステージに自動的にデプロイされます。

  • デフォルトステージ – API の URL のルートパスでリクエストを処理するデフォルトステージ ($default) を作成できます。名前付きステージの場合は、パスの先頭にステージ名を含める必要があります。

  • CORS 設定 – CORS ヘッダーを関数コードで手動で追加する代わりに、送信レスポンスに CORS ヘッダーを追加するように API を設定できます。

REST API は、当初から API Gateway でサポートされている従来の RESTful API です。現在では、より多くのカスタマイズ、統合、および管理機能が追加されています。

REST API の機能

  • 統合タイプ – REST API は、カスタム Lambda 統合をサポートします。カスタム統合では、リクエストのボディだけを関数に送信するか、関数に送信する前にリクエストボディに変換テンプレートを適用できます。

  • アクセスコントロール – REST API では、認証と承認のためのより多くのオプションがサポートされています。

  • モニタリングとトレース – REST API では、AWS X-Ray のトレースと追加のログ記録オプションがサポートされます。

詳細な比較については、API Gateway 開発者ガイドの「HTTP API または REST API の選択」を参照してください。

WebSocket API も API Gateway バージョン 2 API を使用し、同様の機能セットをサポートします。クライアントと API 間の永続的な接続を活用できるアプリケーションには、WebSocket API を使用します。WebSocket API は全二重通信を提供します。つまり、クライアントと API の両方がレスポンスを待たずにメッセージを継続的に送信できます。

HTTP API では、簡略化されたイベント形式 (バージョン 2.0) がサポートされています。次の例は、HTTP API からのイベントを示しています。

event-v2.json – API Gatewayプロキシイベント (HTTP API)

{ "version": "2.0", "routeKey": "ANY /nodejs-apig-function-1G3XMPLZXVXYI", "rawPath": "/default/nodejs-apig-function-1G3XMPLZXVXYI", "rawQueryString": "", "cookies": [ "s_fid=7AABXMPL1AFD9BBF-0643XMPL09956DE2", "regStatus=pre-register" ], "headers": { "accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9", "accept-encoding": "gzip, deflate, br", ... }, "requestContext": { "accountId": "123456789012", "apiId": "r3pmxmplak", "domainName": "r3pmxmplak.execute-api.us-east-2.amazonaws.com", "domainPrefix": "r3pmxmplak", "http": { "method": "GET", "path": "/default/nodejs-apig-function-1G3XMPLZXVXYI", "protocol": "HTTP/1.1", "sourceIp": "205.255.255.176", "userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Safari/537.36" }, "requestId": "JKJaXmPLvHcESHA=", "routeKey": "ANY /nodejs-apig-function-1G3XMPLZXVXYI", "stage": "default", "time": "10/Mar/2020:05:16:23 +0000", "timeEpoch": 1583817383220 }, "isBase64Encoded": true }

詳細については、API Gateway 開発者ガイドの「AWS Lambda 統合」を参照してください。

サンプルアプリケーション

このガイドの GitHub リポジトリには、API Gateway 用の次のサンプルアプリケーションが含まれています。

  • Node.js を使用した API ゲートウェイ – AWS X-Ray のトレースが有効になっている REST API を作成する AWS SAM テンプレートを持つ関数。これには、デプロイ、関数の呼び出し、API のテスト、およびクリーンアップ用のスクリプトが含まれます。

Lambda には、Lambda コンソールで API Gateway アプリケーションを作成するために使用できるブループリントテンプレートも用意されています。