メニュー
Amazon API Gateway
開発者ガイド

Lambda プロキシ統合で API Gateway API をビルドする

このセクションでは、API Gateway コンソールを使用して Lambda 統合で API を作成して検証する方法について説明します。また、Lambda バックエンドで生のリクエストが解析され、アプリロジック (受信リクエストデータによって異なる) が実装される様子についても説明します。API Gateway プロキシ統合の詳細については、「プロキシリソースとのプロキシ統合を設定する」を参照してください。

まず、バックエンドとして、AWS Lambda コンソールを使用して GetStartedLambdaProxyIntegration という名前の次のような Node.js 関数を作成します。次に API Gateway コンソールを使用して、プロキシリソースを通じて GetStartedLambdaProxyIntegration 関数を使用することで、API および Lambda プロキシ統合を作成します。最後に、API をテストする方法を示します。

Lambda プロキシ統合で API の Lambda を作成する

以下の形式の JSON オブジェクトとして、発信者に挨拶を返す Lambda 関数を作成します。

{ "greeting": "Good {time}, {name} of {city}.[ Happy {day}]" }

この例では、{time}morningafternoon、または day で、{name}you か、ユーザー指定のユーザー名になります。{city}World かユーザー指定の都市名、{day} は null か空、またはいずれかの曜日になります。{day} が null または空の場合、Happy {day} 部分は表示されません。Lambda 関数は非常に柔軟性があるため、クライアントは、リクエストヘッダー、パス変数、クエリ文字列パラメータ、および本文を任意に組み合わせて、入力を指定することができます。

API Gateway からバックエンドに渡される内容を表示するには、出力の Lambda 関数にも event オブジェクトを含めます。最後に、Lambda プロキシ統合に必要な基本の出力形式を表す response オブジェクトを作成します。

Lambda 関数は、Node.js、Python、Java、および C# で記述することができます。このチュートリアルでは、Node.js と Java のスニペットを示します。Node.js の実装を Python 関数に拡張するか、Java の実装を C# 関数に拡張することができます。この手順については、以下のトピックを参照してください。

Lambda プロキシ統合用の API の Node.js 関数

次に示す Node.js の Lambda 関数は、"Hello World!" アプリケーションです。この関数は、クライアントによる API Gateway プロキシリソースへのリクエストを含む入力 event パラメーターを解析する方法を示しています。このリソースは、Lambda プロキシ統合を使用して関数と統合されます。また、この関数は、Lambda 関数の出力を API Gateway 用の形式に設定し、結果を HTTP レスポンスとして返す方法も示しています。このタイプの Lambda 関数で従う必要がある入力形式と出力形式の詳細については、「プロキシ統合のための Lambda 関数の入力形式 」および「プロキシ統合のための Lambda 関数の出力形式」を参照してください。

'use strict'; console.log('Loading hello world function'); exports.handler = function(event, context, callback) { let name = "you"; let city = 'World'; let time = 'day'; let day = ''; let responseCode = 200; console.log("request: " + JSON.stringify(event)); // This is a simple illustration of app-specific logic to return the response. // Although only 'event.queryStringParameters' are used here, other request data, // such as 'event.headers', 'event.pathParameters', 'event.body', 'event.stageVariables', // and 'event.requestContext' can be used to determine what response to return. // if (event.queryStringParameters !== null && event.queryStringParameters !== undefined) { if (event.queryStringParameters.name !== undefined && event.queryStringParameters.name !== null && event.queryStringParameters.name !== "") { console.log("Received name: " + event.queryStringParameters.name); name = event.queryStringParameters.name; } } if (event.pathParameters !== null && event.pathParameters !== undefined) { if (event.pathParameters.proxy !== undefined && event.pathParameters.proxy !== null && event.pathParameters.proxy !== "") { console.log("Received proxy: " + event.pathParameters.proxy); city = event.pathParameters.proxy; } } if (event.headers !== null && event.headers !== undefined) { if (event.headers['day'] !== undefined && event.headers['day'] !== null && event.headers['day'] !== "") { console.log("Received day: " + event.headers.day); day = event.headers.day; } } if (event.body !== null && event.body !== undefined) { let body = JSON.parse(event.body) if (body.time) time = body.time; } let greeting = 'Good ' + time + ', ' + name + ' of ' + city + '. '; if (day) greeting += 'Happy ' + day + '!'; var responseBody = { message: greeting, input: event }; // The output from a Lambda proxy integration must be // of the following JSON object. The 'headers' property // is for custom response headers in addition to standard // ones. The 'body' property must be a JSON string. For // base64-encoded payload, you must also set the 'isBase64Encoded' // property to 'true'. var response = { statusCode: responseCode, headers: { "x-custom-header" : "my custom header value" }, body: JSON.stringify(responseBody) }; console.log("response: " + JSON.stringify(response)) callback(null, response); };

API Gateway プロキシ統合の場合、event の入力パラメータには、API Gateway によって JSON オブジェクトとしてマーシャリングされた API リクエストが含まれます。この入力には、リクエストの HTTP メソッド (httpMethod)、パス (path および pathParameters)、クエリパラメータ (queryStringParameters)、ヘッダー (headers)、および適切なペイロード (body) を含めることができます。また、コンテキスト (requestContext) やステージ変数 (stageVariables) を含めることもできます。

この例の Lambda 関数は、event パラメータを解析して、name のクエリ文字列パラメータ、proxy パスパラメータ、day ヘッダ値、およびペイロードの time プロパティを取得します。

その後、responseBody オブジェクトの message プロパティで、指定されたユーザーに挨拶を返します。また、API Gateway によってマーシャリングされた受信リクエストの詳細を表示するために、受信した event オブジェクトをレスポンス本文の input プロパティとして返します。

最後に、終了時に必要な statusCode、適切な headersbody を含む JSON オブジェクトを返します。このオブジェクトが HTTP レスポンスとして API Gateway からクライアントに返されます。

Lambda プロキシ統合用の API の Python 関数

Python で Lambda 関数を作成する」の説明に従って Python Lambda 関数ハンドラを作成します。また、前述の Node.js Lambda 関数で示したプログラミングフローを拡張します。

Lambda プロキシ統合用の API の C# 関数

C# で Lambda 関数を作成する」の説明に従って、C# Lambda 関数ハンドラを作成します。また、以下の Java Lambda 関数で示したプログラミングフローを拡張します。

Lambda プロキシ統合用の API の Java 関数

次に示す Java の Lambda 関数は "Hello World!" アプリケーションであり、Node.js の 同等のものと似ています。この関数では、クライアントから API Gateway プロキシリソースへのリクエストを含み、InputStream オブジェクトとして渡される入力イベントを解析する方法を示します。このリソースは、Lambda プロキシ統合を使用して関数と統合されます。また、context オブジェクトを解析して LambdaLogger を取得する方法も示します。さらに、Java で API Gateway の Lambda 関数の出力をフォーマットして、その結果を HTTP レスポンスとして OutputStream オブジェクトで返す方法も示します。Lambda プロキシ統合の入力形式と出力形式の詳細については、「プロキシ統合のための Lambda 関数の入力形式 」と「プロキシ統合のための Lambda 関数の出力形式」を参照してください。

package examples; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.io.BufferedReader; import java.io.Writer; import com.amazonaws.services.lambda.runtime.RequestStreamHandler; import com.amazonaws.services.lambda.runtime.Context; import com.amazonaws.services.lambda.runtime.LambdaLogger; import org.json.simple.JSONObject; import org.json.simple.JSONArray; import org.json.simple.parser.ParseException; import org.json.simple.parser.JSONParser; public class ProxyWithStream implements RequestStreamHandler { JSONParser parser = new JSONParser(); public void handleRequest(InputStream inputStream, OutputStream outputStream, Context context) throws IOException { LambdaLogger logger = context.getLogger(); logger.log("Loading Java Lambda handler of ProxyWithStream"); BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream)); JSONObject responseJson = new JSONObject(); String name = "you"; String city = "World"; String time = "day"; String day = null; String responseCode = "200"; try { JSONObject event = (JSONObject)parser.parse(reader); if (event.get("queryStringParameters") != null) { JSONObject qps = (JSONObject)event.get("queryStringParameters"); if ( qps.get("name") != null) { name = (String)qps.get("name"); } } if (event.get("pathParameters") != null) { JSONObject pps = (JSONObject)event.get("pathParameters"); if ( pps.get("proxy") != null) { city = (String)pps.get("proxy"); } } if (event.get("headers") != null) { JSONObject hps = (JSONObject)event.get("headers"); if ( hps.get("day") != null) { day = (String)hps.get("day"); } } if (event.get("body") != null) { JSONObject body = (JSONObject)parser.parse((String)event.get("body")); if ( body.get("time") != null) { time = (String)body.get("time"); } } String greeting = "Good " + time + ", " + name + " of " + city + ". "; if (day!=null && day != "") greeting += "Happy " + day + "!"; JSONObject responseBody = new JSONObject(); responseBody.put("input", event.toJSONString()); responseBody.put("message", greeting); JSONObject headerJson = new JSONObject(); headerJson.put("x-custom-header", "my custom header value"); responseJson.put("isBase64Encoded", false); responseJson.put("statusCode", responseCode); responseJson.put("headers", headerJson); responseJson.put("body", responseBody.toString()); } catch(ParseException pex) { responseJson.put("statusCode", "400"); responseJson.put("exception", pex); } logger.log(responseJson.toJSONString()); OutputStreamWriter writer = new OutputStreamWriter(outputStream, "UTF-8"); writer.write(responseJson.toJSONString()); writer.close(); } }

API Gateway のプロキシ統合の場合、入力ストリームには API Gateway によって JSON 文字列としてシリアル化された API リクエストが含まれます。入力データには、リクエストの HTTP メソッド (httpMethod)、パス (pathpathParameters)、クエリパラメーター (queryStringParameters)、ヘッダー (headers)、適切なペイロード (body)、コンテキスト (requestContext)、およびステージ変数 (stageVariables) を含めることができます。

この例の Lambda 関数は、inputStream パラメータを解析して、name のクエリ文字列パラメータ、proxy パスパラメータ、day ヘッダ値、およびペイロードの time プロパティを取得します。ログ記録として、受信した context から LambdaLogger オブジェクトを取得します。

その後、responseBody オブジェクトの message プロパティで、指定されたユーザーに挨拶を返します。また、API Gateway によってマーシャリングされた受信リクエストの詳細を表示するために、レスポンス本文で入力データ (event) を返します。

最後に、終了時に必要な statusCode、適切な headersbody を含む JSON 文字列を返します。この文字列が HTTP レスポンスとして API Gateway からクライアントに返されます。

この関数を Lambda コンソールで作成するには、事前にデプロイパッケージを作成して Lambda にアップロードする必要があります。詳細については、『AWS Lambda 開発者ガイド』の「デプロイパッケージの作成」を参照してください。

Lambda プロキシ統合で API のバックエンドを作成する

Lambda コンソールを使用して API Gateway で Lambda 関数を作成する手順を以下に説明します。

Lambda コンソールで API 用の Lambda 関数とプロキシリソースを作成する

  1. https://console.aws.amazon.com/lambda で Lambda コンソールにサインインします。

  2. コンソールの右上で、Lambda 関数で使用可能なリージョンを選択します。

  3. メインのナビゲーションペインで、[Functions] を選択します。ナビゲーションペインが表示されていない場合は、左上隅のナビゲーションメニューの選択が必要になることがあります。

  4. [Create function] を選択します。次に、[Author from scratch] または [Blueprints] を選択します。この例では、ゼロから関数を作成します。

  5. [Author from scratch] で、次の操作を行います。

    1. [Name] 入力フィールドに関数名を入力します。

    2. [Runtime] ドロップダウンリストから、サポートされているランタイムを選択します。この例では、Node.js 4.3 を使います。

    3. [Role] ドロップダウンリストで、[Choose an existing role]、[Create new role from template(s)]、または [Create a custom role] を選択します。次に、選択に応じて次の手順に従います。

    4. [Create function] を選択して続行します。

      この例では、[Designer] セクションをスキップし、次に [Function code] セクションに移動します。

  6. Node または Python ランタイムの場合、ローカルドライブまたは Amazon S3 から圧縮されたコードファイルをアップロードすることに加えて、インラインコードエディタを使用して Lambda 関数を作成または編集できます。Java または C# ランタイムの場合、ローカルドライブまたは Amazon S3 から、圧縮されたコードファイルをアップロードする必要があります。いずれの場合も、指定されたランタイムのコード例を「 Lambda プロキシ統合で API の Lambda を作成する 」で指定されているように使用します。

  7. [Save] を選択して、Lambda 関数の作成を完了します。

  8. オプション (ただし強く推奨) で、[Test] を選択し、必要な Lambda プロキシ統合リクエスト入力を受け取るようにテストイベントを設定します。

注記

Lambda 関数を作成したリージョンを書き留めます。関数の API を作成する際に必要になります。

Lambda プロキシ統合で API を作成する

次に、API Gateway コンソールを使用して、Lambda 関数用の API とプロキシリソースを作成します。

Lambda 関数用の API とプロキシリソースを作成する

  1. https://console.aws.amazon.com/apigateway で API Gateway コンソールにサインインします。

  2. API を作成するには、[Create new API] (最初の API を作成する場合)または [Create API] (以降の API を作成する場合)を選択します。次に、以下の手順を実行します。

    1. [New API] を選択します。

    2. [API Name] に名前を入力します。

    3. 必要に応じて、[Description] に短い説明を 入力します。

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

    このチュートリアルでは、API 名として LambdaSimpleProxy を使用します。

  3. 子リソースを作成するには、[Resources] ツリーで親リソース項目を選択し、[Actions] ドロップダウンメニューから [Create Resource] を選択します。次に、[New Child Resource] ペインで次の操作を行います。

    1. プロキシリソースを作成するには、[Configure as proxy resource] オプションを選択します。それ以外の場合は、選択しないままにします。

    2. [Resource Name*] テキスト入力フィールドに名前を入力します。

    3. [Resource Path*] テキスト入力フィールドで、新しい名前を入力するか、デフォルト名を使用します。

    4. [Create Resource] を選択します。

    5. 必要に応じて、[Enable API Gateway CORS] を選択します。

    このチュートリアルでは、ルートリソース (/) を親リソースとして使用します。[Configure as proxy resource] を選択します。[Resource Name] は、デフォルトの proxy を使用します。[Resource Path] には /{proxy+} を使用します。[Enable API Gateway CORS] の選択を解除します。

  4. Lambda バックエンドとの統合用に ANY メソッドを設定するには、次の操作を行います。

    1. 先ほど作成されたリソースを選択し、[Actions] ドロップダウンメニューから [Create Method] を選択します。

    2. HTTP メソッドのドロップダウンリストから [ANY] を選択し、チェックマークアイコンを選択して選択内容を保存します。

    3. [Integration type] として [Lambda Function Proxy] を選択します。

    4. [Lambda Region] からリージョンを選択します。

    5. [Lambda Function] に Lambda 関数の名前を入力します。

    6. [Save] を選択します。

    7. [Add Permission to Lambda Function] のプロンプトが表示されたら、[OK] を選択します。

    このチュートリアルでは、[Lambda Function] として以前に作成した「GetStartedLambdaProxyIntegration」を使用します。

Lambda で先ほど作成した プロキシリソース API として、API Gateway はクライアントからの生のリクエストを処理するために Lambda 関数のバックエンドに転送します。リクエストには、リクエストメソッド、パス、クエリ文字列とヘッダーパラメータ、ペイロード、コンテキスト変数、ステージ変数が含まれています。次の手順では、これをテストする方法を説明します。

Lambda プロキシ統合で API をテストする

次の手順では、プロキシ統合をテストする方法について説明します。

プロキシリソース を通じて Lambda の GetStartedLambdaProxyIntegration 関数を呼び出す

  • ブラウザを使用して API の特定のリソースに対して GET メソッドを呼び出すには、次の操作を行います。

    1. 作成した API に対して、[Actions] ドロップダウンメニューから [Deploy API] を選択します (まだ選択していない場合)。API を特定のステージにデプロイするための手順に従います。最後に [Stage Editor] ページに [Invoke URL] が表示されることを確認します。これは API のベース URL です。

    2. 特定のリソースに対する GET リクエストを送信するには、前のステップで取得した [Invoke URL] の値に対して該当するクエリ文字列式を含むリソースパスを追加し、その URL 全体をブラウザのアドレスバーにコピーして Enter を選択します。

    このチュートリアルでは、API を test ステージにデプロイして、API のベース URL (例: https://wt6mne2s9k.execute-api.us-west-2.amazonaws.com/test) を書き留めます。

    デプロイされた API をテストするには、いくつかの方法があります。URL パス変数またはクエリ文字列パラメータのみ使用する GET リクエストの場合は、ブラウザに API のリソース URL を入力します。それ以外のメソッドの場合は、「POSTMAN」または「cURL」などの高度な REST API テストユーティリティを使用する必要があります。

    cURL を使用して デプロイされた API をテストするには

    1. インターネットに接続されているローカルコンピュータでターミナルウィンドウを開きます。

    2. POST /Seattle?time=evening をテストするには

      以下の cURL コマンドをコピーして、ターミナルウィンドウに貼り付けます。

      curl -v -X POST \ 'https://r275xc9bmd.execute-api.us-west-2.amazonaws.com/test/Seattle?time=evening' \ -H 'content-type: application/json' \ -H 'day: Thursday' \ -H 'x-amz-docs-region: us-west-2' \ -d '{ "callerName": "John" }'

      次のペイロードで成功を示すレスポンスが返ります。

      { "message": "Good day, John of Seattle. Happy Friday!", "input": { "resource": "/{proxy+}", "path": "/Seattle", "httpMethod": "POST", "headers": { "day": "Friday" }, "queryStringParameters": { "time": "morning" }, "pathParameters": { "proxy": "Seattle" }, "stageVariables": null, "requestContext": { "path": "/{proxy+}", "accountId": "123456789012", "resourceId": "nl9h80", "stage": "test-invoke-stage", "requestId": "test-invoke-request", "identity": { "cognitoIdentityPoolId": null, "accountId": "123456789012", "cognitoIdentityId": null, "caller": "AIDXXX...XXVJZG", "apiKey": "test-invoke-api-key", "sourceIp": "test-invoke-source-ip", "accessKey": "ASIXXX...XXDQ5A", "cognitoAuthenticationType": null, "cognitoAuthenticationProvider": null, "userArn": "arn:aws:iam::123456789012:user/kdeding", "userAgent": "Apache-HttpClient/4.5.x (Java/1.8.0_131)", "user": "AIDXXX...XXVJZG" }, "resourcePath": "/{proxy+}", "httpMethod": "POST", "apiId": "r275xc9bmd" }, "body": "{ \"callerName\": \"John\" }", "isBase64Encoded": false } }

      前述のメソッドリクエストで POST から PUT に変更した場合も同じレスポンスを受け取ります。

    3. GET /Boston?time=morning をテストするには

      以下の cURL コマンドをコピーして、ターミナルウィンドウに貼り付けます。

      curl -X GET \ 'https://r275xc9bmd.execute-api.us-west-2.amazonaws.com/test/Seattle?time=evening' \ -H 'content-type: application/json' \ -H 'day: Thursday' \ -H 'x-amz-docs-region: us-west-2'

      前述の POST リクエストの結果のような 200 OK Request レスポンスを取得しますが、GET リクエストにはペイロードは含まれません。したがって、body パラメータは null になります。

    注記

    requestContext はキーと値のペアのマップであり、$context 変数に対応します。その結果は API に依存します。API Gateway はマップに新しいキーを追加する場合があります。詳細については、「プロキシ統合のための Lambda 関数の入力形式 」を参照してください。