

# API Gateway での REST API の Lambda 統合
<a name="set-up-lambda-integrations"></a>

 Lambda プロキシ統合または Lambda 非プロキシ (カスタム) 統合を使用して、API メソッドを Lambda 関数に統合できます。

Lambda プロキシ統合では、必要なセットアップを簡単に行えます。統合の HTTP メソッドを POST に設定し、統合エンドポイント URI を特定の Lambda 関数のアクションを呼び出す Lambda 関数の ARN に設定して、ユーザーに代わって Lambda 関数を呼び出す許可を API Gateway に付与します。

Lambda 非プロキシ統合では、プロキシ統合のセットアップステップに加えて、受信リクエストデータがどのように統合リクエストにマッピングされるか、統合レスポンスデータの結果がメソッドレスポンスにどのようにマッピングされるかを指定します。

**Topics**
+ [API Gateway での Lambda プロキシ統合](set-up-lambda-proxy-integrations.md)
+ [API Gateway で Lambda カスタム統合を設定する](set-up-lambda-custom-integrations.md)
+ [バックエンド Lambda 関数の非同期呼び出しをセットアップする](set-up-lambda-integration-async.md)
+ [API Gateway で Lambda エラーを処理する](handle-errors-in-lambda-integration.md)

# API Gateway での Lambda プロキシ統合
<a name="set-up-lambda-proxy-integrations"></a>

次のセクションでは、Lambda プロキシ統合を使用する方法を示します。

**Topics**
+ [API Gateway Lambda プロキシの統合について理解する](#api-gateway-create-api-as-simple-proxy)
+ [複数値のヘッダーとクエリ文字列パラメータのサポート](#apigateway-multivalue-headers-and-parameters)
+ [プロキシ統合のための Lambda 関数の入力形式](#api-gateway-simple-proxy-for-lambda-input-format)
+ [プロキシ統合のための Lambda 関数の出力形式](#api-gateway-simple-proxy-for-lambda-output-format)
+ [AWS CLI を使用して API Gateway の Lambda プロキシ統合をセットアップする](set-up-lambda-proxy-integration-using-cli.md)
+ [OpenAPI 定義を使用してプロキシリソースに Lambda プロキシ統合をセットアップする](api-gateway-set-up-lambda-proxy-integration-on-proxy-resource.md)

## API Gateway Lambda プロキシの統合について理解する
<a name="api-gateway-create-api-as-simple-proxy"></a>

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

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

 API Gateway は Lambda プロキシ統合でクライアントとバックエンド Lambda 関数間にあまり介入しないため、クライアントと統合された Lambda 関数は、API の既存の 統合セットアップを損なうことなく、相互の変更に適応できます。これを有効にするには、クライアントはバックエンド Lambda 関数が制定したアプリケーションプロトコルに従う必要があります。

 任意の API メソッドで Lambda プロキシ統合をセットアップできます。しかし、Lambda プロキシ統合は、汎用的なプロキシリソースが含まれる API メソッドに設定されていると、より強力です。汎用的なプロキシリソースは、特別なテンプレートパス変数である `{proxy+}` 、キャッチオールである `ANY` メソッドプレースホルダー、または両方によって示すことができます。クライアントは、受信リクエストのバックエンド Lambda 関数に、入力をリクエストパラメータまたは適切なペイロードとして渡すことができます。リクエストパラメータには、ヘッダー、URL パス変数、クエリ文字列パラメータ、および適切なペイロードが含まれます。統合された Lambda 関数は、リクエストを処理して、必要な入力がない場合に意味のあるエラーメッセージでクライアントに応答する前に、すべての入力ソースを検証します。

 `ANY` の汎用的な HTTP メソッドと `{proxy+}` の汎用的なリソースと統合されている API メソッドを呼び出す際、クライアントは `ANY` の代わりに特定の HTTP メソッドを持つリクエストを送信します。クライアントはさらに、`{proxy+}` の代わりに特定の URL パスを指定し、要求されるヘッダー、クエリ文字列パラメータ、または適切なペイロードを含めます。

 次のリストは、Lambda プロキシ統合での異なる API メソッドのランタイム動作を要約しています。
+ `ANY /{proxy+}`: クライアントは特定の HTTP メソッドを選択し、特定のリソースパス階層を設定する必要があり、Lambda 関数にデータを入力として渡すために任意のヘッダー、クエリ文字列パラメータ、および適切なペイロードを設定できます。
+ `ANY /res`: クライアントは特定の HTTP メソッドを選択する必要があり、Lambda 関数にデータを入力として渡すために任意のヘッダー、クエリ文字列パラメータ、および適切なペイロードを設定できます。
+ `GET|POST|PUT|... /{proxy+}`: クライアントは特定のリソースパス階層を設定することができ、Lambda 関数にデータを入力として渡すために任意のヘッダー、クエリ文字列パラメータ、および適切なペイロードを設定できます。
+  `GET|POST|PUT|... /res/{path}/...`: クライアントは (`{path}` 変数に) 特定のパスセグメントを選択する必要があり、Lambda 関数に入力データを渡すために任意のリクエストヘッダー、クエリ文字列パラメータ、および適切なペイロードを設定できます。
+  `GET|POST|PUT|... /res`: クライアントは Lambda 関数に入力データを渡すために任意のリクエストヘッダー、クエリ文字列パラメータ、および適切なペイロードを設定できます。

 `{proxy+}` のプロキシリソースと `{custom}` のカスタムリソースの両方が、テンプレートパス変数として表現されています。ただし、`{proxy+}` はパス階層に沿った任意のリソースを参照できますが、`{custom}` は特定のパスセグメントのみを参照します。たとえば、食料品店はオンラインの製品インベントリを部門名、農産物カテゴリ、および製品タイプで整理しています。食料品店のウェブサイトは、カスタムリソースの次のテンプレートパス変数によって、利用可能な製品を表すことができます: `/{department}/{produce-category}/{product-type}`。たとえば、リンゴは `/produce/fruit/apple` で表され、ニンジンは `/produce/vegetables/carrot` で表されます。また、`/{proxy+}` を使用して、顧客がオンラインストアで買い物中に検索できる任意の部門、農産物カテゴリ、または製品タイプを表すことができます。たとえば、`/{proxy+}` は次のいずれかのアイテムを参照できます。
+ `/produce`
+ `/produce/fruit`
+ `/produce/vegetables/carrot`

 顧客が利用可能な製品、その農産物カテゴリ、および関連するストア部門を検索できるようにするには、`GET /{proxy+}` の単一メソッドを読み取り専用アクセス権限で公開することができます。同様に、責任者が `produce` 部門のインベントリをアップデートできるようにするには、別の `PUT /produce/{proxy+}` の単一メソッドを読み取り/書き込みアクセス権限でセットアップできます。レジ係が野菜の合計を更新できるようにするには、`POST /produce/vegetables/{proxy+}` メッセージを読み取り/書き込みアクセス権限でセットアップできます。店長が任意のアクションを任意の利用可能な製品に実行できるようにするには、オンラインストア開発者は `ANY /{proxy+}` メソッドを読み取り/書き込みアクセス権限で公開できます。いずれの場合も、実行時には、顧客または従業員は選択された部門のあるタイプの特定の製品、製品部門の特定の農産物カテゴリ、または特定の部門を選択する必要があります。



API Gateway プロキシ統合のセットアップの詳細については、「[プロキシリソースとのプロキシ統合を設定する](api-gateway-set-up-simple-proxy.md)」を参照してください。

 プロキシ統合は、クライアントがバックエンド要件のより詳細な知識を持っていることを要求します。したがって、最適なアプリケーションパフォーマンスとユーザーエクスペリエンスを確保するために、バックエンド開発者はバックエンドの要件をクライアント開発者に明確に伝え、要件が満たされない場合は堅牢なエラーフィードバックメカニズムを提供する必要があります。

## 複数値のヘッダーとクエリ文字列パラメータのサポート
<a name="apigateway-multivalue-headers-and-parameters"></a>

API Gateway は、同じ名前を持つ複数のヘッダーやクエリ文字列パラメータをサポートするようになりました。複数値ヘッダーや単一値ヘッダー、およびパラメータを、同じリクエストとレスポンスで組み合わせることができます。詳細については、「[プロキシ統合のための Lambda 関数の入力形式](#api-gateway-simple-proxy-for-lambda-input-format)」および「[プロキシ統合のための Lambda 関数の出力形式](#api-gateway-simple-proxy-for-lambda-output-format)」を参照してください。

## プロキシ統合のための Lambda 関数の入力形式
<a name="api-gateway-simple-proxy-for-lambda-input-format"></a>

Lambda プロキシ統合では、API Gateway がクライアントリクエスト全体をバックエンド Lambda 関数の入力 `event` パラメータにマップします。次の例は、API Gateway が Lambda プロキシ統合に送信するイベントの構造を示しています。

この例では、API Gateway への呼び出しが次のようになっていることを前提としています。

```
curl 'https://a1b2c3.execute-api.us-east-1.amazonaws.com/my/path?parameter1=value1&parameter2=value1&parameter2=value2&parameter3=value1,value2' -H 'header1: value1' -H 'header2: value1' -H 'header2: value2' -H 'header3: value1,value2'
```

出力は次のようになります。

```
{
  "resource": "/my/path",
  "path": "/my/path",
  "httpMethod": "GET",
  "headers": {
      "header1": "value1",
      "header2": "value2",
      "header3": "value1,value2"
  },
  "multiValueHeaders": {
    "header1": ["value1"],
    "header2": ["value1","value2"],
    "header3": ["value1,value2"]
  },
  "queryStringParameters": {
      "parameter1": "value1",
      "parameter2": "value2",
      "parameter3": "value1,value2"
  },
  "multiValueQueryStringParameters": {
    "parameter1": ["value1"],
    "parameter2": ["value1","value2"],
    "parameter3": ["value1,value2"]
  },
  "requestContext": {
    "accountId": "123456789012",
    "apiId": "id",
    "authorizer": {
      "claims": null,
      "scopes": null
    },
    "domainName": "id.execute-api.us-east-1.amazonaws.com",
    "domainPrefix": "id",
    "extendedRequestId": "request-id",
    "httpMethod": "GET",
    "identity": {
      "accessKey": null,
      "accountId": null,
      "caller": null,
      "cognitoAuthenticationProvider": null,
      "cognitoAuthenticationType": null,
      "cognitoIdentityId": null,
      "cognitoIdentityPoolId": null,
      "principalOrgId": null,
      "sourceIp": "IP",
      "user": null,
      "userAgent": "user-agent",
      "userArn": null,
      "clientCert": {
        "clientCertPem": "CERT_CONTENT",
        "subjectDN": "www.example.com",
        "issuerDN": "Example issuer",
        "serialNumber": "a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1",
        "validity": {
          "notBefore": "May 28 12:30:02 2019 GMT",
          "notAfter": "Aug  5 09:36:04 2021 GMT"
        }
      }
    },
    "path": "/my/path",
    "protocol": "HTTP/1.1",
    "requestId": "id=",
    "requestTime": "04/Mar/2020:19:15:17 +0000",
    "requestTimeEpoch": 1583349317135,
    "resourceId": null,
    "resourcePath": "/my/path",
    "stage": "$default"
  },
  "pathParameters": null,
  "stageVariables": null,
  "body": "Hello from Lambda!",
  "isBase64Encoded": false
}
```

**注記**  
入力値は、次のようになります。  
`headers` キーには、単一値のヘッダーのみを含めることができます。
`multiValueHeaders` キーには、複数値のヘッダーや単一値のヘッダーを含めることができます。
`headers` と `multiValueHeaders` の両方の値を指定した場合、API Gateway はそれらを単一のリストにマージします。同じキーと値のペアが両方で指定された場合にのみ、`multiValueHeaders` の値が、マージされたリストに表示されます。

バックエンド Lambda 関数への入力では、`requestContext` オブジェクトはキーと値のペアのマップです。各ペアにおいて、キーは [\$1context](api-gateway-mapping-template-reference.md#context-variable-reference) 変数プロパティの名前であり、値はそのプロパティの値です。API Gateway は、マップに新しいキーを追加する場合があります。

有効になっている機能に応じて、`requestContext` マップは API ごとに異なる場合があります。たとえば、前述の例では、認可タイプが指定されていないため、`$context.authorizer.*` や `$context.identity.*` プロパティは存在しません。認可タイプが指定されると、API Gateway は、認可されたユーザー情報を `requestContext.identity` オブジェクト内の統合エンドポイントに次のように渡します。
+ 認可タイプが `AWS_IAM` の場合、認可されるユーザー情報には `$context.identity.*` プロパティが含まれます。
+ 認可タイプが `COGNITO_USER_POOLS` (Amazon Cognito オーソライザー) の場合、認可されるユーザー情報には `$context.identity.cognito*` および `$context.authorizer.claims.*` プロパティが含まれます。
+ 認可タイプが `CUSTOM` (Lambda オーソライザー) の場合、認可されるユーザー情報には `$context.authorizer.principalId` およびその他の該当する `$context.authorizer.*` プロパティが含まれます。

## プロキシ統合のための Lambda 関数の出力形式
<a name="api-gateway-simple-proxy-for-lambda-output-format"></a>

Lambda プロキシ統合では、以下の JSON 形式に従って出力を返すために、API Gateway はバックエンドの Lambda 関数を必要とします。

```
{
    "isBase64Encoded": true|false,
    "statusCode": httpStatusCode,
    "headers": { "headerName": "headerValue", ... },
    "multiValueHeaders": { "headerName": ["headerValue", "headerValue2", ...], ... },
    "body": "..."
}
```

出力では、次のようになります。
+ 余分なレスポンスヘッダーが返されない場合、`headers` および `multiValueHeaders` キーは指定されません。
+ `headers` キーには、単一値のヘッダーのみを含めることができます。
+ `multiValueHeaders` キーには、複数値のヘッダーや単一値のヘッダーを含めることができます。`multiValueHeaders` キーを使用して、単一値のヘッダーを含めて、すべてのヘッダーを指定することができます。
+ `headers` と `multiValueHeaders` の両方の値を指定した場合、API Gateway はそれらを単一のリストにマージします。同じキーと値のペアが両方で指定された場合にのみ、`multiValueHeaders` の値が、マージされたリストに表示されます。

Lambda プロキシ統合に対して CORS を有効にするには、`Access-Control-Allow-Origin:domain-name` を出力 `headers` に追加する必要があります。`domain-name` は、任意のドメイン名に対して `*` にすることができます。出力 `body` は、メソッドレスポンスペイロードとしてフロントエンドにマーシャリングされます。`body` がバイナリ BLOB の場合、`isBase64Encoded` を `true` に設定し、`*/*` を [**バイナリメディアタイプ**] に設定することで、Base64 エンコード文字列としてエンコードできます。それ以外の場合は、`false` に設定するか、指定しないでおくことができます。

**注記**  
バイナリサポートの有効化に関する詳細については、[API Gateway コンソールを使用したバイナリサポートの有効化](api-gateway-payload-encodings-configure-with-console.md) を参照してください。サンプルの Lambda 関数については、「[API Gateway のLambda プロキシ統合からバイナリメディアを返す](lambda-proxy-binary-media.md)」を参照してください。

関数出力が別の形式である場合、API Gateway は `502 Bad Gateway` エラーレスポンスを返します。

Node.js での Lambda 関数でレスポンスを返すには、次のようなコマンドを使用できます。
+ 成功した場合の結果を返すには、`callback(null, {"statusCode": 200, "body": "results"})` を呼び出します。
+ 例外をスローするには、`callback(new Error('internal server error'))` を呼び出します。
+ クライアント側エラーの場合 (必要なパラメータがない場合など)、`callback(null, {"statusCode": 400, "body": "Missing parameters of ..."})` を呼び出して、例外をスローせずにエラーを返すことができます。

Node.js の Lambda `async` 関数では、同等の構文は次のようになります。
+ 成功した場合の結果を返すには、`return {"statusCode": 200, "body": "results"}` を呼び出します。
+ 例外をスローするには、`throw new Error("internal server error")` を呼び出します。
+ クライアント側エラーの場合 (必要なパラメータがない場合など)、`return {"statusCode": 400, "body": "Missing parameters of ..."}` を呼び出して、例外をスローせずにエラーを返すことができます。

# AWS CLI を使用して API Gateway の Lambda プロキシ統合をセットアップする
<a name="set-up-lambda-proxy-integration-using-cli"></a>

このセクションでは、AWS CLI を使用して Lambda プロキシ統合で API をセットアップする方法について説明します。API Gateway コンソールを使用してプロキシリソースに Lambda プロキシ統合を設定する詳しい手順については、「[チュートリアル: Lambda プロキシ統合を使用して REST API を作成する](api-gateway-create-api-as-simple-proxy-for-lambda.md)」を参照してください。

たとえば、次のサンプル Lambda 関数を API のバックエンドとして使用します。

```
export const handler = async(event, context) => {
    console.log('Received event:', JSON.stringify(event, null, 2));
    var res ={
        "statusCode": 200,
        "headers": {
            "Content-Type": "*/*"
        }
    };
    var greeter = 'World';
    if (event.greeter && event.greeter!=="") {
        greeter =  event.greeter;
    } else if (event.body && event.body !== "") {
        var body = JSON.parse(event.body);
        if (body.greeter && body.greeter !== "") {
            greeter = body.greeter;
        }
    } else if (event.queryStringParameters && event.queryStringParameters.greeter && event.queryStringParameters.greeter !== "") {
        greeter = event.queryStringParameters.greeter;
    } else if (event.multiValueHeaders && event.multiValueHeaders.greeter && event.multiValueHeaders.greeter != "") {
        greeter = event.multiValueHeaders.greeter.join(" and ");
    } else if (event.headers && event.headers.greeter && event.headers.greeter != "") {
        greeter = event.headers.greeter;
    } 
    res.body = "Hello, " + greeter + "!";
    return res
};
```

これを [API Gateway で Lambda カスタム統合を設定する](set-up-lambda-custom-integrations.md) の Lambdaカスタム統合のセットアップと比較すると、この Lambda 関数への入力はリクエストパラメータと本文で表現できます。クライアントが同じ入力データを渡すことができるように、自由度は高くなっています。ここで、クライアントは、クエリ文字列パラメータ、ヘッダ、または本文プロパティとして Greeter の名前を渡すことができます。この関数は、カスタムの Lambda 統合をサポートすることもできます。API のセットアップはより簡単です。メソッドレスポンスまたは統合レスポンスを設定することはありません。

**AWS CLI を使用して Lambda プロキシ統合をセットアップするには**

1. 次の [create-rest-api](https://docs.aws.amazon.com/cli/latest/reference/apigateway/create-rest-api.html) コマンドを使用して、API を作成します。

   ```
   aws apigateway create-rest-api --name 'HelloWorld (AWS CLI)'
   ```

   出力は次のようになります。

   ```
   {
       "name": "HelloWorldProxy (AWS CLI)", 
       "id": "te6si5ach7",
       "rootResourceId" : "krznpq9xpg",
       "createdDate": 1508461860
   }
   ```

   この例全体で、API `id` (`te6si5ach7`) と `rootResourceId` (`krznpq9xpg`) を使用します。

1. 次の [create-resource](https://docs.aws.amazon.com/cli/latest/reference/apigateway/create-resource.html) コマンドを使用して、`/greeting` の API Gateway [リソース](https://docs.aws.amazon.com/apigateway/latest/api/API_Resource.html) を作成します。

   ```
   aws apigateway create-resource \
         --rest-api-id te6si5ach7 \
         --parent-id krznpq9xpg \
         --path-part {proxy+}
   ```

   出力は次のようになります。

   ```
   {
       "path": "/{proxy+}", 
       "pathPart": "{proxy+}", 
       "id": "2jf6xt", 
       "parentId": "krznpq9xpg"
   }
   ```

   次のステップでは、`{proxy+}` リソースの `id` 値 (`2jf6xt`) を使用して `/{proxy+}` リソースにメソッドを作成します。

1. 次の [put-method](https://docs.aws.amazon.com/cli/latest/reference/apigateway/put-method.html) を使用して、`ANY /{proxy+}` の `ANY` メソッドリクエストを作成します。

   ```
   aws apigateway put-method --rest-api-id te6si5ach7 \
          --resource-id 2jf6xt \
          --http-method ANY \
          --authorization-type "NONE"
   ```

   出力は次のようになります。

   ```
   {
       "apiKeyRequired": false, 
       "httpMethod": "ANY", 
       "authorizationType": "NONE"
   }
   ```

   この API メソッドでは、クライアントはバックエンドの Lambda 関数からお知らせを受信または送信できます。

1. 次の [put-integration](https://docs.aws.amazon.com/cli/latest/reference/apigateway/put-integration.html) コマンドを使用して、`ANY /{proxy+}` メソッドと `HelloWorld` という名前の Lambda 関数との統合を設定します。この関数は、`"Hello, {name}!"` パラメータが提供されている場合は `greeter`、クエリ文字列パラメータが設定されていない場合は `"Hello, World!"` のメッセージでリクエストに応答します。

   ```
   aws apigateway put-integration \
         --rest-api-id te6si5ach7 \
         --resource-id 2jf6xt \
         --http-method ANY \
         --type AWS_PROXY \
         --integration-http-method POST \
         --uri arn:aws:apigateway:us-west-2:lambda:path/2015-03-31/functions/arn:aws:lambda:us-west-2:123456789012:function:HelloWorld/invocations \
         --credentials arn:aws:iam::123456789012:role/apigAwsProxyRole
   ```
**重要**  
Lambda 統合では、[関数呼び出しの Lambda サービスアクションの仕様](https://docs.aws.amazon.com/lambda/latest/api/API_Invoke.html)に従って、統合リクエストに `POST` の HTTP メソッドを使用する必要があります。`apigAwsProxyRole` の IAM ロールは、`apigateway` サービスが Lambda 関数を呼び出せるようにするポリシーが必要です。IAM 権限の詳細については、「[API を呼び出すための API Gateway アクセス許可モデル](permissions.md#api-gateway-control-access-iam-permissions-model-for-calling-api)」を参照してください。

   出力は次のようになります。

   ```
   {
       "passthroughBehavior": "WHEN_NO_MATCH", 
       "cacheKeyParameters": [], 
       "uri": "arn:aws:apigateway:us-west-2:lambda:path/2015-03-31/functions/arn:aws:lambda:us-west-2:1234567890:function:HelloWorld/invocations", 
       "httpMethod": "POST", 
       "cacheNamespace": "vvom7n", 
       "credentials": "arn:aws:iam::1234567890:role/apigAwsProxyRole", 
       "type": "AWS_PROXY"
   }
   ```

   `credentials` の IAM ロールを指定する代わりに、[add-permission](https://docs.aws.amazon.com/cli/latest/reference/lambda/add-permission.html) コマンドを使用してリソースベースのアクセス許可を追加できます。これは、API Gateway コンソールが行うことです。

1. 次の [create-deployment](https://docs.aws.amazon.com/cli/latest/reference/apigateway/create-deployment.html) コマンドを使用して、API を `test` ステージにデプロイします。

   ```
   aws apigateway create-deployment  \
         --rest-api-id te6si5ach7 \
         --stage-name test
   ```

1. ターミナルで次の cURL コマンドを使用して API をテストします。

   `?greeter=jane` のクエリ文字列パラメータを使用して API を呼び出します。

   ```
   curl -X GET 'https://te6si5ach7.execute-api.us-west-2.amazonaws.com/test/greeting?greeter=jane'
   ```

   `greeter:jane` のヘッダーパラメータを使用して API を呼び出します。

   ```
   curl -X GET https://te6si5ach7.execute-api.us-west-2.amazonaws.com/test/hi \
     -H 'content-type: application/json' \
     -H 'greeter: jane'
   ```

   `{"greeter":"jane"}` の本文を使用して API を呼び出します。

   ```
   curl -X POST https://te6si5ach7.execute-api.us-west-2.amazonaws.com/test/hi \
     -H 'content-type: application/json' \
     -d '{ "greeter": "jane" }'
   ```

   すべてのケースで、出力は、次のレスポンス本文を持つ 200 レスポンスです。

   ```
   Hello, jane!
   ```

# OpenAPI 定義を使用してプロキシリソースに Lambda プロキシ統合をセットアップする
<a name="api-gateway-set-up-lambda-proxy-integration-on-proxy-resource"></a>

プロキシリソースに Lambda プロキシ統合タイプをセットアップするには、greedy パスパラメータ (`/parent/{proxy+}` など) を使用して API リソースを作成し、このリソースを `arn:aws:lambda:us-west-2:123456789012:function:SimpleLambda4ProxyResource` メソッドで Lambda 関数のバックエンド (`ANY` など) と統合します。greedy パスパラメータは、API リソースパスの末尾にある必要があります。プロキシ以外のリソースと同様に、API Gateway コンソールを使用するか、OpenAPI 定義ファイルをインポートするか、API Gateway REST API を直接呼び出すことによって、プロキシリソースをセットアップできます。

以下の OpenAPI API 定義ファイルは、`SimpleLambda4ProxyResource` という名前の Lambda 関数を使用して統合された API とプロキシリソースの例を示しています。

------
#### [ OpenAPI 3.0 ]

```
{
   "openapi": "3.0.0",
   "info": {
      "version": "2016-09-12T17:50:37Z",
      "title": "ProxyIntegrationWithLambda"
   },
   "paths": {
      "/{proxy+}": {
         "x-amazon-apigateway-any-method": {
            "parameters": [
               {
                  "name": "proxy",
                  "in": "path",
                  "required": true,
                  "schema": {
                     "type": "string"
                  }
               }
            ],
            "responses": {},
            "x-amazon-apigateway-integration": {
               "responses": {
                  "default": {
                     "statusCode": "200"
                  }
               },
               "uri": "arn:aws:apigateway:us-east-1:lambda:path/2015-03-31/functions/arn:aws:lambda:us-east-1:123456789012:function:SimpleLambda4ProxyResource/invocations",
               "passthroughBehavior": "when_no_match",
               "httpMethod": "POST",
               "cacheNamespace": "roq9wj",
               "cacheKeyParameters": [
                  "method.request.path.proxy"
               ],
               "type": "aws_proxy"
            }
         }
      }
   },
   "servers": [
      {
         "url": "https://gy415nuibc.execute-api.us-east-1.amazonaws.com/{basePath}",
         "variables": {
            "basePath": {
              "default": "/testStage"
            }
         }
      }
   ]
}
```

------
#### [ OpenAPI 2.0 ]

```
{
  "swagger": "2.0",
  "info": {
    "version": "2016-09-12T17:50:37Z",
    "title": "ProxyIntegrationWithLambda"
  },
  "host": "gy415nuibc.execute-api.us-east-1.amazonaws.com",
  "basePath": "/testStage",
  "schemes": [
    "https"
  ],
  "paths": {
    "/{proxy+}": {
      "x-amazon-apigateway-any-method": {
        "produces": [
          "application/json"
        ],
        "parameters": [
          {
            "name": "proxy",
            "in": "path",
            "required": true,
            "type": "string"
          }
        ],
        "responses": {},
        "x-amazon-apigateway-integration": {
          "responses": {
            "default": {
              "statusCode": "200"
            }
          },
          "uri": "arn:aws:apigateway:us-east-1:lambda:path/2015-03-31/functions/arn:aws:lambda:us-east-1:123456789012:function:SimpleLambda4ProxyResource/invocations",
          "passthroughBehavior": "when_no_match",
          "httpMethod": "POST",
          "cacheNamespace": "roq9wj",
          "cacheKeyParameters": [
            "method.request.path.proxy"
          ],
          "type": "aws_proxy"
        }
      }
    }
  }
}
```

------

Lambda プロキシ統合では、ランタイムに API Gateway は受信リクエストを Lambda 関数の入力 `event` パラメータにマッピングします。入力にはリクエストメソッド、パス、ヘッダー、クエリ文字列パラメータ、ペイロード、関連コンテキスト、定義済みステージ変数が含まれています。入力形式については「[プロキシ統合のための Lambda 関数の入力形式](set-up-lambda-proxy-integrations.md#api-gateway-simple-proxy-for-lambda-input-format)」で説明しています。API Gateway が Lambda 出力を HTTP レスポンスに正常にマッピングするには、Lambda 関数は、「[プロキシ統合のための Lambda 関数の出力形式](set-up-lambda-proxy-integrations.md#api-gateway-simple-proxy-for-lambda-output-format)」で説明されている形式で結果を出力する必要があります。

`ANY` メソッドによるプロキシリソースの Lambda プロキシ統合では、単一のバックエンド Lambda 関数が、プロキシリソースを通じてすべてのリクエストのイベントハンドラーの役割を果たします。たとえば、トラフィックパターンを記録するために、プロキシリソースの URL パスで `/state/city/street/house` を使用してリクエストを送信することによって、モバイルデバイスから州、市、番地、建物などの場所情報を送信できます。バックエンドの Lambda 関数は、URL パスを解析し、場所情報のタプルを DynamoDB テーブルに挿入できます。

# API Gateway で Lambda カスタム統合を設定する
<a name="set-up-lambda-custom-integrations"></a>

 カスタムの Lambda 統合または非プロキシ統合をセットアップする方法を表示するには、`GET /greeting?greeter={name}` メソッドを公開する API Gateway API を作成して、Lambda 関数を呼び出します。API には、次の Lambda 関数の例のいずれかを使用します。

次の Lambda 関数の例のいずれかを使用します。

------
#### [ Node.js ]

```
'use strict';
var days = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];            
var times = ['morning', 'afternoon', 'evening', 'night', 'day'];

export const handler = async(event) => {
  console.log(event);
  // Parse the input for the name, city, time and day property values
  let name = event.name === null || event.name === undefined || event.name === "" ? 'you' : event.name;
  let city = event.city === undefined ? 'World' : event.city;
  let time = times.indexOf(event.time)<0 ? 'day' : event.time;
  let day = days.indexOf(event.day)<0 ? null : event.day;

  // Generate a greeting
  let greeting = 'Good ' + time + ', ' + name + ' of ' + city + '. ';
  if (day) greeting += 'Happy ' + day + '!';
  
  // Log the greeting to CloudWatch
  console.log('Hello: ', greeting);
  
  // Return a greeting to the caller
  return greeting;
};
```

------
#### [ Python ]

```
import json


def lambda_handler(event, context):
    print(event)
    res = {
        "statusCode": 200,
        "headers": {
            "Content-Type": "*/*"
        }
    }

    if event['greeter'] == "":
        res['body'] = "Hello, World"
    elif (event['greeter']):
        res['body'] = "Hello, " + event['greeter'] + "!"
    else:
        raise Exception('Missing the required greeter parameter.')

    return res
```

------

この関数は、`"Hello, {name}!"` パラメータの値が空白でない文字列の場合は、`greeter` のメッセージで応答します。`"Hello, World!"` の値が空の文字列の場合は、`greeter` のメッセージを返します。着信リクエストで greeter パラメータが設定されていない場合、この関数は `"Missing the required greeter parameter."` のエラーメッセージを返します。関数名を `HelloWorld` とします。

これは、Lambda コンソールで、または AWS CLI を使用して作成できます。このセクションでは、次の ARN を使用してこの関数を参照します。

```
arn:aws:lambda:us-east-1:123456789012:function:HelloWorld
```

バックエンドに Lambda 関数を設定すると、API のセットアップに進みます。<a name="set-up-lambda-custom-integration-using-cli"></a>

**AWS CLI を使用して Lambda カスタム統合をセットアップするには**

1. 次の [create-rest-api](https://docs.aws.amazon.com/cli/latest/reference/apigateway/create-rest-api.html) コマンドを使用して、API を作成します。

   ```
   aws apigateway create-rest-api --name 'HelloWorld (AWS CLI)'
   ```

   出力は次のようになります。

   ```
   {
       "name": "HelloWorld (AWS CLI)", 
       "id": "te6si5ach7",
       "rootResourceId" : "krznpq9xpg",
       "createdDate": 1508461860
   }
   ```

   この例全体で、API `id` (`te6si5ach7`) と `rootResourceId` (`krznpq9xpg`) を使用します。

1. 次の [create-resource](https://docs.aws.amazon.com/cli/latest/reference/apigateway/create-resource.html) コマンドを使用して、`/greeting` の API Gateway [リソース](https://docs.aws.amazon.com/apigateway/latest/api/API_Resource.html) を作成します。

   ```
   aws apigateway create-resource \
         --rest-api-id te6si5ach7 \
         --parent-id krznpq9xpg \
         --path-part greeting
   ```

   出力は次のようになります。

   ```
   {
       "path": "/greeting", 
       "pathPart": "greeting", 
       "id": "2jf6xt", 
       "parentId": "krznpq9xpg"
   }
   ```

   次のステップでは、`greeting` リソースの `id` 値 (`2jf6xt`) を使用して `/greeting` リソースにメソッドを作成します。

1. 次の [put-method](https://docs.aws.amazon.com/cli/latest/reference/apigateway/put-method.html) コマンドを使用して、`GET /greeting?greeter={name}` の API メソッドリクエストを作成します。

   ```
   aws apigateway put-method --rest-api-id te6si5ach7 \
          --resource-id 2jf6xt \
          --http-method GET \
          --authorization-type "NONE" \
          --request-parameters method.request.querystring.greeter=false
   ```

   出力は次のようになります。

   ```
   {
       "apiKeyRequired": false, 
       "httpMethod": "GET", 
       "authorizationType": "NONE", 
       "requestParameters": {
           "method.request.querystring.greeter": false
       }
   }
   ```

   この API メソッドでは、クライアントはバックエンドの Lambda 関数からお知らせを受信できます。バックエンドは匿名の発信者または匿名でない発信者のいずれかを処理する必要があるため、この `greeter` パラメータはオプションです。

1. 次の [put-method-response](https://docs.aws.amazon.com/cli/latest/reference/apigateway/put-method-response.html) コマンドを使用して、`GET /greeting?greeter={name}` メソッドリクエストに対する `200 OK` レスポンスを設定します。

   ```
   aws apigateway put-method-response \
           --rest-api-id te6si5ach7 \ 
           --resource-id 2jf6xt \
           --http-method GET \
           --status-code 200
   ```

   

1. 次の [put-integration](https://docs.aws.amazon.com/cli/latest/reference/apigateway/put-integration.html) コマンドを使用して、`GET /greeting?greeter={name}` メソッドと `HelloWorld` という名前の Lambda 関数との統合を設定します。この関数は、`"Hello, {name}!"` パラメータが提供されている場合は `greeter`、クエリ文字列パラメータが設定されていない場合は `"Hello, World!"` のメッセージでリクエストに応答します。

   ```
   aws apigateway put-integration \
           --rest-api-id te6si5ach7 \
           --resource-id 2jf6xt \
           --http-method GET \
           --type AWS \
           --integration-http-method POST \
           --uri arn:aws:apigateway:us-east-1:lambda:path/2015-03-31/functions/arn:aws:lambda:us-east-1:123456789012:function:HelloWorld/invocations \
           --request-templates '{"application/json":"{\"greeter\":\"$input.params('greeter')\"}"}' \
           --credentials arn:aws:iam::123456789012:role/apigAwsProxyRole
   ```

   ここで指定されたマッピングテンプレートは、`greeter` クエリ文字列パラメータを JSON ペイロードの `greeter` プロパティに変換します。Lambda 関数への入力を本文で表現する必要があるため、これが必要になります。
**重要**  
Lambda 統合では、[関数呼び出しの Lambda サービスアクションの仕様](https://docs.aws.amazon.com/lambda/latest/api/API_Invoke.html)に従って、統合リクエストに `POST` の HTTP メソッドを使用する必要があります。`uri` パラメータは、関数呼び出しアクションの ARN です。  
出力は次のようになります。

   ```
   {
       "passthroughBehavior": "WHEN_NO_MATCH", 
       "cacheKeyParameters": [], 
       "uri": "arn:aws:apigateway:us-east-1:lambda:path/2015-03-31/functions/arn:aws:lambda:us-east-1:123456789012:function:HelloWorld/invocations", 
       "httpMethod": "POST", 
       "requestTemplates": {
           "application/json": "{\"greeter\":\"$input.params('greeter')\"}"
       }, 
       "cacheNamespace": "krznpq9xpg", 
       "credentials": "arn:aws:iam::123456789012:role/apigAwsProxyRole", 
       "type": "AWS"
   }
   ```

   `apigAwsProxyRole` の IAM ロールは、`apigateway` サービスが Lambda 関数を呼び出せるようにするポリシーが必要です。`credentials` の IAM ロールを指定する代わりに、[add-permission](https://docs.aws.amazon.com/cli/latest/reference/lambda/add-permission.html) コマンドを呼び出して、リソースベースのアクセス許可を追加することができます。これは、API Gateway コンソールがこれらのアクセス許可を追加する方法です。

1. 次の [put-integration-response](https://docs.aws.amazon.com/cli/latest/reference/apigateway/put-integration-response.html) コマンドを使用して、Lambda 関数の出力を `200 OK` メソッドレスポンスとしてクライアントに渡すための統合レスポンスを設定します。

   ```
    aws apigateway put-integration-response \
           --rest-api-id te6si5ach7 \
           --resource-id 2jf6xt \
           --http-method GET \
           --status-code 200 \
           --selection-pattern ""
   ```

   選択パターンを空の文字列に設定すると、`200 OK` レスポンスがデフォルトになります。

   出力は次のようになります。

   ```
    {
       "selectionPattern": "", 
       "statusCode": "200"
   }
   ```

1. 次の [create-deployment](https://docs.aws.amazon.com/cli/latest/reference/apigateway/create-deployment.html) コマンドを使用して、API を `test` ステージにデプロイします。

   ```
   aws apigateway create-deployment \
           --rest-api-id te6si5ach7 \
           --stage-name test
   ```

1.  ターミナルで次の cURL コマンドを使用して API をテストします。

   ```
   curl -X GET 'https://te6si5ach7.execute-api.us-west-2.amazonaws.com/test/greeting?greeter=me' \
     -H 'authorization: AWS4-HMAC-SHA256 Credential={access_key}/20171020/us-west-2/execute-api/aws4_request, SignedHeaders=content-type;host;x-amz-date, Signature=f327...5751'
   ```

# バックエンド Lambda 関数の非同期呼び出しをセットアップする
<a name="set-up-lambda-integration-async"></a>

Lambda 非プロキシ (カスタム) 統合では、デフォルトでバックエンド Lambda 関数が同期的に呼び出されます。これは、ほとんどの REST API 操作に必要な動作です。ただし、一部のアプリケーションでは非同期で作業を実行する必要があります (バッチオペレーションまたは長時間レイテンシーオペレーションとして実行)。通常、これは別々のバックエンドコンポーネントで実行されます。この場合は、バックエンド Lambda 関数は非同期に呼び出され、フロントエンドの REST API メソッドは結果を返しません。

`'Event'` を [Lambda 呼び出しタイプ](https://docs.aws.amazon.com/lambda/latest/dg/lambda-invocation.html)として指定することで、Lambda 非プロキシ統合用の Lambda 関数を非同期的に呼び出すように設定できます。これは次のように行います。

## API Gateway コンソールで Lambda 非同期呼び出しを設定する
<a name="asynchronous-invocation-console-examples"></a>

すべての呼び出しを非同期にするには：
+ **[統合リクエスト]** で、静的な値として `'Event'` を使用して `X-Amz-Invocation-Type` ヘッダーを追加します。

クライアントが、呼び出しが非同期か同期かを判断するには、次のようにします。

1. **[メソッドリクエスト]** で、`InvocationType` ヘッダーを追加します。

1. **[統合リクエスト]** で、マッピング式として `method.request.header.InvocationType` を使用して `X-Amz-Invocation-Type` ヘッダーを追加します。

1. クライアントは、非同期呼び出しには API リクエストに`InvocationType: Event` ヘッダーを含めるか、同期呼び出しには `InvocationType: RequestResponse` を含めることができます。

## OpenAPI を使用した Lambda 非同期呼び出しの設定
<a name="asynchronous-invocation-OpenAPI-examples"></a>

すべての呼び出しを非同期にするには：
+  `X-Amz-Invocation-Type` ヘッダーを **x-amazon-apigateway-integration** セクションに追加します。

  ```
  "x-amazon-apigateway-integration" : {
            "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:my-function/invocations",
            "responses" : {
              "default" : {
                "statusCode" : "200"
              }
            },
            "requestParameters" : {
              "integration.request.header.X-Amz-Invocation-Type" : "'Event'"
            },
            "passthroughBehavior" : "when_no_match",
            "contentHandling" : "CONVERT_TO_TEXT"
          }
  ```

クライアントが、呼び出しが非同期か同期かを判断するには、次のようにします。

1.  任意の [OpenAPI Path Item オブジェクト](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#pathItemObject)に次のヘッダーを追加します。

   ```
   "parameters" : [ {
   "name" : "InvocationType",
   "in" : "header",
   "schema" : {
     "type" : "string"
   }
   } ]
   ```

1.  `X-Amz-Invocation-Type` ヘッダーを **x-amazon-apigateway-integration** セクションに追加します。

   ```
   "x-amazon-apigateway-integration" : {
             "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:my-function/invocations",
             "responses" : {
               "default" : {
                 "statusCode" : "200"
               }
             },
             "requestParameters" : {
               "integration.request.header.X-Amz-Invocation-Type" : "method.request.header.InvocationType"
             },
             "passthroughBehavior" : "when_no_match",
             "contentHandling" : "CONVERT_TO_TEXT"
           }
   ```

1.  クライアントは、非同期呼び出しには API リクエストに`InvocationType: Event` ヘッダーを含めるか、同期呼び出しには `InvocationType: RequestResponse` を含めることができます。

## CloudFormation を使用して Lambda 非同期呼び出しを設定する
<a name="asynchronous-invocation-cfn-examples"></a>

以下の CloudFormation テンプレートは、非同期呼び出し用に `AWS::ApiGateway::Method` を設定する方法を示しています。

すべての呼び出しを非同期にするには：

```
AsyncMethodGet:
    Type: 'AWS::ApiGateway::Method'
    Properties:
      RestApiId: !Ref Api
      ResourceId: !Ref AsyncResource
      HttpMethod: GET
      ApiKeyRequired: false
      AuthorizationType: NONE
      Integration:
        Type: AWS
        RequestParameters:
          integration.request.header.X-Amz-Invocation-Type: "'Event'"
        IntegrationResponses:
            - StatusCode: '200'
        IntegrationHttpMethod: POST
        Uri: !Sub arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${myfunction.Arn}$/invocations
      MethodResponses:
        - StatusCode: '200'
```

クライアントが、呼び出しが非同期か同期かを判断するには、次のようにします。

```
AsyncMethodGet:
    Type: 'AWS::ApiGateway::Method'
    Properties:
      RestApiId: !Ref Api
      ResourceId: !Ref AsyncResource
      HttpMethod: GET
      ApiKeyRequired: false
      AuthorizationType: NONE
      RequestParameters:
        method.request.header.InvocationType: false
      Integration:
        Type: AWS
        RequestParameters:
          integration.request.header.X-Amz-Invocation-Type: method.request.header.InvocationType
        IntegrationResponses:
            - StatusCode: '200'
        IntegrationHttpMethod: POST
        Uri: !Sub arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${myfunction.Arn}$/invocations
      MethodResponses:
        - StatusCode: '200'
```

 クライアントは、非同期呼び出しには API リクエストに`InvocationType: Event` ヘッダーを含めるか、同期呼び出しには `InvocationType: RequestResponse` を含めることができます。

# API Gateway で Lambda エラーを処理する
<a name="handle-errors-in-lambda-integration"></a>

 Lambda カスタム統合の場合、統合レスポンスで Lambda によって返されたエラーを、クライアントの標準 HTTP エラーレスポンスにマップする必要があります。そうしないと、Lambda のエラーはデフォルトで `200 OK` レスポンスとして返されるため、API ユーザーは直感的に理解できません。

 Lambda から返されるエラーには、標準エラーとカスタムエラーの 2 種類があります。API では、これらを異なる方法で処理する必要があります。

 Lambda プロキシ統合では、Lambda は次の形式で出力を返す必要があります。

```
{
  "isBase64Encoded" : "boolean",
  "statusCode": "number",
  "headers": { ... },
  "body": "JSON string"
}
```

この出力で、通常、`statusCode` の `4XX` はクライアントエラー、`5XX` はサーバーエラーです。API Gateway では、これらのエラーを処理する方法として、指定された `statusCode` に従って Lambda エラーを HTTP エラーレスポンスにマッピングします。API Gateway がクライアントへのレスポンスの一部としてエラータイプ (`InvalidParameterException` など) を渡すには、Lambda 関数がヘッダー (`"X-Amzn-ErrorType":"InvalidParameterException"` など) を `headers` プロパティに含める必要があります。

**Topics**
+ [API Gateway で標準の Lambda エラーを処理する](#handle-standard-errors-in-lambda-integration)
+ [API Gateway でカスタム Lambda エラーを処理する](#handle-custom-errors-in-lambda-integration)

## API Gateway で標準の Lambda エラーを処理する
<a name="handle-standard-errors-in-lambda-integration"></a>

AWS Lambda の標準エラーは次の形式になります。

```
{
  "errorMessage": "<replaceable>string</replaceable>",
  "errorType": "<replaceable>string</replaceable>",
  "stackTrace": [
    "<replaceable>string</replaceable>",
    ...
  ]
}
```

 ここで、`errorMessage` はエラーの文字列式です。`errorType` は、言語に依存するエラーまたは例外タイプです。`stackTrace` は、エラーの発生につながったスタックトレースを示す文字列式のリストです。

 たとえば、次の JavaScript (Node.js) Lambda 関数について考えてみます。

```
export const handler = function(event, context, callback) {
    callback(new Error("Malformed input ..."));
};
```

この関数は、`Malformed input ...` をエラーメッセージとする、次の Lambda 標準エラーを返します。

```
{
  "errorMessage": "Malformed input ...",
  "errorType": "Error",
  "stackTrace": [
    "export const handler (/var/task/index.js:3:14)"
  ]
}
```

 同様に、次の例は同じ `Exception` をエラーメッセージとし、`Malformed input ...` をスローする Python Lambda 関数です。

```
def lambda_handler(event, context):
    raise Exception('Malformed input ...')
```

 この関数は、次の Lambda 標準エラーを返します。

```
{
  "stackTrace": [
    [
      "/var/task/lambda_function.py",
      3,
      "lambda_handler",
      "raise Exception('Malformed input ...')"
    ]
  ],
  "errorType": "Exception",
  "errorMessage": "Malformed input ..."
}
```

 `errorType` プロパティと `stackTrace` プロパティの値は、言語に依存します。この標準エラーは、`Error` オブジェクトの拡張または `Exception` クラスのサブクラスである各エラーオブジェクトにも適用されます。

 Lambda の標準エラーをメソッドレスポンスにマッピングするには、まず該当する Lambda エラーの HTTP スタータスコードを確認する必要があります。次に、その HTTP ステータスコードに関連付けられた [IntegrationResponse](https://docs.aws.amazon.com/apigateway/latest/api/API_IntegrationResponse.html) の `[selectionPattern](https://docs.aws.amazon.com/apigateway/latest/api/API_IntegrationResponse.html#selectionPattern)` プロパティで正規表現パターンを設定します。API Gateway コンソールの場合、この `selectionPattern` は各統合レスポンスの下の **[統合レスポンス]** セクションに、**[Lambda エラーの正規表現]** として表示されます。

**注記**  
API Gateway は、レスポンスマッピングに Java パターンスタイルの正規表現を使用します。詳細については、Oracle ドキュメントの「[パターン](https://docs.oracle.com/javase/8/docs/api/java/util/regex/Pattern.html)」を参照してください。

 例えば、次の [put-integration-response](https://docs.aws.amazon.com/cli/latest/reference/apigateway/put-integration-response.html) を使用して新しい `selectionPattern` 式を設定します。

```
aws apigateway put-integration-response --rest-api-id z0vprf0mdh --resource-id x3o5ih --http-method GET --status-code 400 --selection-pattern "Malformed.*" --region us-west-2
```

 [メソッドレスポンス](api-gateway-method-settings-method-response.md#setup-method-response-status-code)で対応するエラーコード (`400`) も必ず設定します。そうしないと、ランタイムに API Gateway から無効な設定エラーレスポンスがスローされます。

**注記**  
 ランタイムに、API Gateway は Lambda エラーの `errorMessage` を `selectionPattern` プロパティの正規表現のパターンと照合します。一致すると、API Gateway は Lambda エラーを、対応する HTTP ステータスコードの HTTP レスポンスとして返します。一致しない場合、API Gateway はエラーをデフォルトレスポンスとして返すか、デフォルトレスポンスが設定されていなければ、無効な設定例外をスローします。  
 特定のレスポンスで `selectionPattern` の値を `.*` に設定すると、このレスポンスはデフォルトのレスポンスとしてリセットされます。このような選択パターンは null (任意の未指定のエラーメッセージ) を含むすべてのエラーメッセージに一致するためです。その結果のマッピングにより、デフォルトのマッピングが上書きされます。`.+` を選択パターンとして使用してレスポンスをフィルタする場合は、改行 ('`\n`) 文字を含むレスポンスには一致しない可能性があることに注意してください。

 `selectionPattern` を使用して既存の AWS CLI 値を更新するには、[update-integration-response](https://docs.aws.amazon.com/cli/latest/reference/apigateway/update-integration-response.html) オペレーションを呼び出し、`/selectionPattern` のパス値を `Malformed*` パターンの指定された正規表現式に置き換えます。



API Gateway コンソールを使用して `selectionPattern` 式を設定するには、指定した HTTP ステータスコードの統合レスポンスを設定または更新するときに、**[Lambda エラーの正規表現]** テキストボックスに式を入力します。

## API Gateway でカスタム Lambda エラーを処理する
<a name="handle-custom-errors-in-lambda-integration"></a>

 AWS Lambda では、前のセクションで説明した標準エラーの代わりにカスタムエラーオブジェクトを JSON 文字列として返すことができます。エラーは、任意の有効な JSON オブジェクトです。たとえば、次の JavaScript (Node.js) Lambda 関数はカスタムエラーを返します。

```
export const handler = (event, context, callback) => {
    ...
    // Error caught here:
    var myErrorObj = {
        errorType : "InternalServerError",
        httpStatus : 500,
        requestId : context.awsRequestId,
        trace : {
            "function": "abc()",
            "line": 123,
            "file": "abc.js"
        }
    }
    callback(JSON.stringify(myErrorObj));
};
```

 `myErrorObj` を呼び出して関数を終了する前に、`callback` オブジェクトを JSON 文字列に変換する必要があります。そうしないと、`myErrorObj` は `"[object Object]"` の文字列として返されます。API のメソッドを前の Lambda 関数と統合すると、API Gateway は以下の内容をペイロードとする統合レスポンスを受け取ります。

```
{
    "errorMessage": "{\"errorType\":\"InternalServerError\",\"httpStatus\":500,\"requestId\":\"e5849002-39a0-11e7-a419-5bb5807c9fb2\",\"trace\":{\"function\":\"abc()\",\"line\":123,\"file\":\"abc.js\"}}"
}
```

 通常の統合レスポンスと同様に、このエラーレスポンスはそのままメソッドレスポンスに渡すことができます。または、マッピングテンプレートを使用してペイロードを別の形式に変換することもできます。次の例は、ステータスコードが `500` のメソッドレスポンスの本文マッピングテンプレートです。

```
{
    errorMessage: $input.path('$.errorMessage');
}
```

このテンプレートは、カスタムエラーの JSON 文字列が含まれている統合レスポンス本文を、次のメソッドレスポンス本文に変換します。このメソッドレスポンス本文には、カスタムエラーの JSON オブジェクトが含まれています。

```
{
    "errorMessage" : {
        errorType : "InternalServerError",
        httpStatus : 500,
        requestId : context.awsRequestId,
        trace : {
            "function": "abc()",
            "line": 123,
            "file": "abc.js"
        }
    }
};
```

 API の要件によっては、カスタムエラープロパティの一部または全部をメソッドレスポンスのヘッダーパラメータとして渡す必要があります。そのためには、統合レスポンス本文からメソッドレスポンスヘッダーにカスタムエラーマッピングを適用します。

たとえば、次の OpenAPI 拡張は、`errorMessage.errorType`、`errorMessage.httpStatus`、`errorMessage.trace.function`、および `errorMessage.trace` プロパティから、それぞれ `error_type`、`error_status`、`error_trace_function`、および `error_trace` ヘッダーへのマッピングを定義します。

```
"x-amazon-apigateway-integration": {
    "responses": {
        "default": {
          "statusCode": "200",
          "responseParameters": {
            "method.response.header.error_trace_function": "integration.response.body.errorMessage.trace.function",
            "method.response.header.error_status": "integration.response.body.errorMessage.httpStatus",
            "method.response.header.error_type": "integration.response.body.errorMessage.errorType",
            "method.response.header.error_trace": "integration.response.body.errorMessage.trace"
          },
          ...
        }
    }
}
```

 ランタイムに、API Gateway は `integration.response.body` パラメータを逆シリアル化してヘッダーマッピングを行います。ただし、この逆シリアル化は、Lambda のカスタムエラーレスポンスの本文からヘッダーへのマッピングにのみ適用され、`$input.body` を使用した本文から本文へのマッピングには適用されません。これらのカスタムエラーの本文からヘッダーへのマッピングでは、クライアントはメソッドレスポンスの一部として以下のヘッダーを受け取ります (`error_status`、`error_trace`、`error_trace_function`、および `error_type` をメソッドリクエストで宣言している場合)。

```
"error_status":"500",
"error_trace":"{\"function\":\"abc()\",\"line\":123,\"file\":\"abc.js\"}",
"error_trace_function":"abc()",
"error_type":"InternalServerError"
```

統合レスポンス本文の `errorMessage.trace` プロパティは複合プロパティです。これは JSON 文字列として `error_trace` ヘッダーにマッピングされます。