AWS Lambda
開発者ガイド

チュートリアル: Amazon API Gateway で AWS Lambda を使用する

この例では、Amazon API Gateway を使用してシンプルな API を作成します。Amazon API Gateway はリソースとメソッドの集合体です。このチュートリアルでは、1 つのリソース (DynamoDBManager) を作成し、それに対する 1 つのメソッド (POST) を定義します。このメソッドでは-Lambda 関数 (LambdaFunctionOverHttps) が使用されます。つまり、HTTPS エンドポイントで API を呼び出すと、Amazon API Gateway が Lambda 関数を呼び出します。

DynamoDBManager リソースの POST メソッドでは、以下の DynamoDB オペレーションがサポートされます。

  • 項目を作成、更新、削除する。

  • 項目を読み取る。

  • 項目をスキャンする。

  • テストに使用できる、DynamoDB に関連しないその他のオペレーション (echo、ping)。

POST リクエストで送信するリクエストペイロードによって、DynamoDB オペレーションが識別され、必要なデータが提供されます。例:

  • DynamoDB の項目の作成オペレーションのリクエストペイロードの例を以下に示します。

    { "operation": "create", "tableName": "lambda-apigateway", "payload": { "Item": { "id": "1", "name": "Bob" } } }
  • DynamoDB の Read Item オペレーションのリクエストペイロードの例を以下に示します。

    { "operation": "read", "tableName": "lambda-apigateway", "payload": { "Key": { "id": "1" } } }
  • echo オペレーションのリクエストペイロードの例を以下に示します。リクエストボディに以下のデータを使用して、HTTP POST リクエストをエンドポイントに送信します。

    { "operation": "echo", "payload": { "somekey1": "somevalue1", "somekey2": "somevalue2" } }

注記

API Gateway には、次のような高度な機能があります。

  • リクエスト全体のパススルーAWS_PROXY 統合タイプを使用して、Lambda 関数で HTTP リクエスト全体 (リクエストボディだけでなく) を受信し、HTTP レスポンス (レスポンス本文だけでなく) を設定できます。

  • キャッチオールメソッドANY キャッチオールメソッドを使用して、API リソースのすべてのメソッドを単一のマッピングを使用する単一の Lambda 関数にマッピングできます。

  • キャッチオールリソース – 新しいパスパラメーター ({proxy+})) を使用して、リソースのすべてのサブパスを、追加構成を必要とせずに Lambda 関数にマッピングできます。

これらの API ゲートウェイ機能の詳細については、「プロキシリソースのプロキシ統合を設定する」を参照してください。

前提条件

実行ロールを作成する

AWS リソースにアクセスするためのアクセス権限を関数に付与する実行ロールを作成します。

実行ロールを作成するには

  1. IAM コンソールのロールページを開きます。

  2. [ロールの作成] を選択します。

  3. 次のプロパティでロールを作成します。

    • 信頼されたエンティティ – Lambda

    • ロール名lambda-apigateway-role

    • [アクセス許可] – DynamoDB および CloudWatch Logs のアクセス許可を含むカスタムポリシー。

      { "Version": "2012-10-17", "Statement": [ { "Sid": "Stmt1428341300017", "Action": [ "dynamodb:DeleteItem", "dynamodb:GetItem", "dynamodb:PutItem", "dynamodb:Query", "dynamodb:Scan", "dynamodb:UpdateItem" ], "Effect": "Allow", "Resource": "*" }, { "Sid": "", "Resource": "*", "Action": [ "logs:CreateLogGroup", "logs:CreateLogStream", "logs:PutLogEvents" ], "Effect": "Allow" } ] }

カスタムポリシーには、関数がデータを DynamoDB に書き込んでログをアップロードするために必要なアクセス許可が含まれています。後で使用できるようにロールの Amazon リソースネーム (ARN) をメモします。

関数を作成する

以下のコード例では、Kinesis イベント入力を受け取り、含まれるメッセージを処理します。このコードでは説明のために、受信イベントデータの一部が CloudWatch Logs に書き込まれます。

注記

他の言語によるサンプルコードについては、「サンプル関数コード」を参照してください。

例 index.js

console.log('Loading function'); var AWS = require('aws-sdk'); var dynamo = new AWS.DynamoDB.DocumentClient(); /** * Provide an event that contains the following keys: * * - operation: one of the operations in the switch statement below * - tableName: required for operations that interact with DynamoDB * - payload: a parameter to pass to the operation being performed */ exports.handler = function(event, context, callback) { //console.log('Received event:', JSON.stringify(event, null, 2)); var operation = event.operation; if (event.tableName) { event.payload.TableName = event.tableName; } switch (operation) { case 'create': dynamo.put(event.payload, callback); break; case 'read': dynamo.get(event.payload, callback); break; case 'update': dynamo.update(event.payload, callback); break; case 'delete': dynamo.delete(event.payload, callback); break; case 'list': dynamo.scan(event.payload, callback); break; case 'echo': callback(null, "Success"); break; case 'ping': callback(null, "pong"); break; default: callback('Unknown operation: ${operation}'); } };

関数を作成するには

  1. サンプルコードを index.js という名前のファイルにコピーします。

  2. デプロイパッケージを作成します。

    $ zip function.zip index.js
  3. create-function コマンドを使用して Lambda 関数を作成します。

    $ aws lambda create-function --function-name LambdaFunctionOverHttps \ --zip-file fileb://function.zip --handler index.handler --runtime nodejs8.10 \ --role arn:aws:iam::123456789012:role/service-role/lambda-apigateway-role

Lambda 関数をテストする

サンプルイベントデータを使用して手動で関数を呼び出します。コンソール UI では、実行の要約、ユーザーのコードによって書き込まれたログ、関数が返した結果 (コンソールでは常に同期実行される — RequestResponse 呼び出しタイプを使用して Lambda 関数を呼び出す) などの実行結果の確認用にユーザーに分かりやすいインターフェイスが提供されているため、コンソールを使用して関数を呼び出すことをお勧めします。

Lambda 関数をテストするには

  1. 以下の JSON をファイルにコピーし、input.txt という名前で保存します。

    { "operation": "echo", "payload": { "somekey1": "somevalue1", "somekey2": "somevalue2" } }
  2. 次の invoke コマンドを実行します。

    $ aws lambda invoke --function-name LambdaFunctionOverHttps \ --payload fileb://input.txt outputfile.txt

Amazon API Gateway を使用して API を作成する

このステップでは、Amazon API Gateway を使用して作成した API 内のメソッドに Lambda 関数を関連付け、エンドツーエンドエクスペリエンスをテストします。つまり、HTTP リクエストが API メソッドに送信されると、Amazon API Gateway は Lambda 関数を呼び出します。

最初に、Amazon API Gateway を使用して、1 つのリソース (DynamoDBManager) と 1 つのメソッド (POST) を持つ API (DynamoDBOperations) を作成します。POST メソッドを Lambda 関数に関連付けます。次に、エンドツーエンドエクスペリエンスをテストします。

API の作成

次の create-rest-api コマンドを実行して、このチュートリアル用の DynamoDBOperations API を作成します。

$ aws apigateway create-rest-api --name DynamoDBOperations { "id": "bs8fqo6bp0", "name": "DynamoDBOperations", "createdDate": 1539803980, "apiKeySource": "HEADER", "endpointConfiguration": { "types": [ "EDGE" ] } }

別のコマンドで使用できるように API ID を保存します。API のルートリソースの ID も必要です。この ID を取得するには、get-resources コマンドを実行します。

$ API=bs8fqo6bp0 $ aws apigateway get-resources --rest-api-id $API { "items": [ { "path": "/", "id": "e8kitthgdb" } ] }

この時点ではルートリソースのみですが、次のステップでリソースを追加します。

API でリソースを作成する

次の create-resource コマンドを実行して、前のセクションで作成した API のリソース (DynamoDBManager) を作成します。

$ aws apigateway create-resource --rest-api-id $API --path-part DynamoDBManager \ --parent-id e8kitthgdb { "path": "/DynamoDBManager", "pathPart": "DynamoDBManager", "id": "resource-id", "parentId": "e8kitthgdb" }

応答内の ID を書き留めます。これは、作成した DynamoDBManager リソースの ID です。

リソースに対する POST メソッドを作成する

次の put-method コマンドを実行して、API の DynamoDBManager リソースで POST メソッドを作成します。

$ RESOURCE=iuig5w $ aws apigateway put-method --rest-api-id $API --resource-id $RESOURCE \ --http-method POST --authorization-type NONE { "apiKeyRequired": false, "httpMethod": "POST", "authorizationType": "NONE" }

--authorization-type パラメーターに、このメソッドでは未認証リクエストがサポートされていることを意味する NONE を指定します。この値はテスト用には適切ですが、本稼働時にはキーベースまたはロールベースのいずれかの認証を使用する必要があります。

Lambda 関数を POST メソッドの送信先に設定する

次のコマンドを実行して、Lambda 関数を POST メソッドの統合ポイントとして設定します。これは、POST メソッドエンドポイントの HTTP リクエストを行ったときに Amazon API Gateway が呼び出すメソッドです。このコマンドと他のコマンドは、アカウント ID とリージョンを含む ARN を使用します。これらを変数に保存します (アカウント ID は、関数の作成に使用したロール ARN にあります)。

$ REGION=us-east-2 $ ACCOUNT=123456789012 $ aws apigateway put-integration --rest-api-id $API --resource-id $RESOURCE \ --http-method POST --type AWS --integration-http-method POST \ --uri arn:aws:apigateway:$REGION:lambda:path/2015-03-31/functions/arn:aws:lambda:$REGION:$ACCOUNT:function:LambdaFunctionOverHttps/invocations { "type": "AWS", "httpMethod": "POST", "uri": "arn:aws:apigateway:us-east-2:lambda:path/2015-03-31/functions/arn:aws:lambda:us-east-2:123456789012:function:LambdaFunctionOverHttps/invocations", "passthroughBehavior": "WHEN_NO_MATCH", "timeoutInMillis": 29000, "cacheNamespace": "iuig5w", "cacheKeyParameters": [] }

--integration-http-method は、API Gateway が AWS Lambda との通信に使用するメソッドです。--uri は、Amazon API Gateway がリクエストを送信できるエンドポイントの一意識別子です。

POST メソッドのレスポンスおよび統合レスポンスの content-type を、以下のように JSON に設定します。

  • 次のコマンドを実行して、POST メソッドのレスポンスを JSON に設定します。これが、API メソッドが返すレスポンスのタイプになります。

    $ aws apigateway put-method-response --rest-api-id $API \ --resource-id $RESOURCE --http-method POST \ --status-code 200 --response-models application/json=Empty { "statusCode": "200", "responseModels": { "application/json": "Empty" } }
  • 次のコマンドを実行して、POST メソッドの統合レスポンスを JSON に設定します。これが、Lambda 関数が返すレスポンスのタイプになります。

    $ aws apigateway put-integration-response --rest-api-id $API \ --resource-id $RESOURCE --http-method POST \ --status-code 200 --response-templates application/json="" { "statusCode": "200", "responseTemplates": { "application/json": null } }

API をデプロイする

このステップでは、作成した API を prod というステージにデプロイします。

$ aws apigateway create-deployment --rest-api-id $API --stage-name prod { "id": "20vgsz", "createdDate": 1539820012 }

API に呼び出しアクセス許可を付与する

Amazon API Gateway を使用して API を作成し、デプロイしたので、テストできます。まず、POST メソッドに HTTP リクエストを送信したときに、Amazon API Gateway が Lambda 関数を呼び出すことができるようにアクセス許可を追加する必要があります。

これを行うには、Lambda 関数に関連付けられているアクセス権限ポリシーにアクセス権限を追加する必要があります。次の AWS Lambda add-permission コマンドを実行して、Lambda 関数 (LambdaFunctionOverHttps) を呼び出すアクセス権限を Amazon API Gateway サービスプリンシパル (apigateway.amazonaws.com) に付与します。

$ aws lambda add-permission --function-name LambdaFunctionOverHttps \ --statement-id apigateway-test-2 --action lambda:InvokeFunction \ --principal apigateway.amazonaws.com \ --source-arn "arn:aws:execute-api:$REGION:$ACCOUNT:$API/*/POST/DynamoDBManager" { "Statement": "{\"Sid\":\"apigateway-test-2\",\"Effect\":\"Allow\",\"Principal\":{\"Service\":\"apigateway.amazonaws.com\"},\"Action\":\"lambda:InvokeFunction\",\"Resource\":\"arn:aws:lambda:us-east-2:123456789012:function:LambdaFunctionOverHttps\",\"Condition\":{\"ArnLike\":{\"AWS:SourceArn\":\"arn:aws:execute-api:us-east-2:123456789012:mnh1yprki7/*/POST/DynamoDBManager\"}}}" }

テストを行うには、このアクセス権限を付与する必要があります (Amazon API Gateway に移動し、[Test] を選択して API メソッドをテストする場合は、このアクセス権限が必要です)。--source-arn には、ステージ値としてワイルドカード文字 (*) を指定する (テスト用のみを表す) ことに注意してください。これにより、API をデプロイせずにテストできます。

次に、同じコマンドをもう一度実行しますが、今度は、Lambda 関数を呼び出すためのアクセス権限を、デプロイ済み API に付与します。

$ aws lambda add-permission --function-name LambdaFunctionOverHttps \ --statement-id apigateway-prod-2 --action lambda:InvokeFunction \ --principal apigateway.amazonaws.com \ --source-arn "arn:aws:execute-api:$REGION:$ACCOUNT:$API/prod/POST/DynamoDBManager" { "Statement": "{\"Sid\":\"apigateway-prod-2\",\"Effect\":\"Allow\",\"Principal\":{\"Service\":\"apigateway.amazonaws.com\"},\"Action\":\"lambda:InvokeFunction\",\"Resource\":\"arn:aws:lambda:us-east-2:123456789012:function:LambdaFunctionOverHttps\",\"Condition\":{\"ArnLike\":{\"AWS:SourceArn\":\"arn:aws:execute-api:us-east-2:123456789012:mnh1yprki7/prod/POST/DynamoDBManager\"}}}" }

デプロイ済み API が Lambda 関数を呼び出すためのアクセス権限を持つように、このアクセス権限を付与します。--source-arn には、API のデプロイ時に使用したステージ名である prod を指定することに注意してください。

Amazon DynamoDB テーブルの作成

Lambda 関数が使用する DynamoDB テーブルを作成します。

DynamoDB テーブルを作成するには

  1. DynamoDB コンソールを開きます。

  2. [Create table] を選択します。

  3. 次の設定でテーブルを作成します。

    • [Table name (テーブル名)] – lambda-apigateway

    • [プライマリキー] – id (文字列)

  4. [作成] を選択します。

HTTP リクエストを使用して関数をトリガーする

このステップでは、POST メソッドのエンドポイントに HTTP リクエストを送信する準備ができています。Curl または Amazon API Gateway で提供されているメソッド (test-invoke-method) のいずれかを使用できます。

リソース (DynamoDBManager) のエンドポイントに HTTP POST リクエストを送信するには、Amazon API Gateway の CLI コマンドを使用できます。Amazon API Gateway はデプロイ済みであるため、Curl を使用して同じオペレーション用のメソッドを呼び出すことができます。

Lambda 関数では、DynamoDB テーブル内に項目を作成する create オペレーションの使用がサポートされています。このオペレーションをリクエストするには、次の JSON を使用します。

例 create-item.json

{ "operation": "create", "tableName": "lambda-apigateway", "payload": { "Item": { "id": "1234ABCD", "number": 5 } } }

テスト入力を create-item.json というファイルに保存します。test-invoke-method Amazon API Gateway コマンドを実行して HTTP POST メソッドリクエストをリソース (DynamoDBManager) エンドポイントに送信します。

$ aws apigateway test-invoke-method --rest-api-id $API \ --resource-id $RESOURCE --http-method POST --path-with-query-string "" \ --body file://create-item.json

または、次の Curl コマンドを使用することもできます。

$ curl -X POST -d "{\"operation\":\"create\",\"tableName\":\"lambda-apigateway\",\"payload\":{\"Item\":{\"id\":\"1\",\"name\":\"Bob\"}}}" https://$API.execute-api.$REGION.amazonaws.com/prod/DynamoDBManager

Lambda 関数でサポートされている echo オペレーション用のリクエストを送信するには、次のリクエストペイロードを使用できます。

例 echo.json

{ "operation": "echo", "payload": { "somekey1": "somevalue1", "somekey2": "somevalue2" } }

テスト入力を echo.json というファイルに保存します。リクエストボディに前述の JSON を使用して、リソース (DynamoDBManager) のエンドポイントに POST メソッドの HTTP リクエストを送信する、Amazon API Gateway の test-invoke-method CLI コマンドを実行します。

$ aws apigateway test-invoke-method --rest-api-id $API \ --resource-id $RESOURCE --http-method POST --path-with-query-string "" \ --body file://echo.json

または、次の Curl コマンドを使用することもできます。

$ curl -X POST -d "{\"operation\":\"echo\",\"payload\":{\"somekey1\":\"somevalue1\",\"somekey2\":\"somevalue2\"}}" https://$API.execute-api.$REGION.amazonaws.com/prod/DynamoDBManager