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

Amazon API Gateway で AWS Lambda を使用する

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

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

エンドポイントの Lambda 関数への追加

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

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

  2. 関数を選択します。

  3. [ 機能の概要 ] で、[ トリガーを追加 ] を選択します。

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

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

  6. [API type] (API タイプ) で、[HTTP API] を選択します。詳細については、API タイプを参照してください。

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

  8. [Add] (追加) をクリックします。

プロキシ統合

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

API パス形式

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

  • /prod/user - prod ステージおよび 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 }

レスポンスの形式

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 }

Permissions

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:111122223333:function:nodejs-apig-function-1G3MXMPLXVXYI", "Condition": { "StringEquals": { "aws:SourceAccount": "111122223333" }, "ArnLike": { "aws:SourceArn": "arn:aws:execute-api:us-east-2:111122223333:ktyvxmpls1/*/GET/" } } } ] }

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

次の 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/user - prod ステージの user リソースにおけるすべてのメソッド。

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

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

API Gateway API でのエラーの処理

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

注記

API Gateway は、Lambda 呼び出しを再試行しません。Lambda がエラーを返す場合、API Gateway はクライアントにエラーレスポンスを返します。

以下の例では、関数エラーになり 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 の機能

  • 統合タイプ - 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 integrations を参照してください。

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

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

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

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