

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# API Gateway 中 REST API 的 Lambda 整合
<a name="set-up-lambda-integrations"></a>

 您可以使用 Lambda 代理整合或 Lambda 非代理 (自訂) 整合，將 API 方法與 Lambda 函數整合。

在 Lambda 代理整合中，必要設定非常簡單。將整合的 HTTP 方法設定為 POST、將整合端點 URI 設定為特定 Lambda 函數之 Lambda 函數呼叫動作的 ARN，並且允許 API Gateway 代表您呼叫 Lambda 函數。

在 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)
+ [使用 設定 API Gateway 的 Lambda 代理整合 AWS CLI](set-up-lambda-proxy-integration-using-cli.md)
+ [使用 Lambda 代理整合與 OpenAPI 定義設定代理資源](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 函數。函數會存取其他服務的許多資源或功能 AWS ，包括呼叫其他 Lambda 函數。

 在 Lambda 代理整合中，當用戶端提交一個 API 請求時，API Gateway 會對整合的 Lambda 函數傳遞[事件物件](#api-gateway-simple-proxy-for-lambda-input-format)，但不會保留請求參數的順序。此[請求資料](#api-gateway-simple-proxy-for-lambda-input-format)包含請求標頭、查詢字串參數、URL 路徑變數、承載與 API 組態資料。組態資料可包含目前的部署階段名稱、階段變數、使用者身分或授權內容 (如果有)。後端 Lambda 函數會剖析傳入請求資料，以判斷其所傳回的回應。若要讓 API Gateway 將 Lambda 輸出當作 API 回應傳遞至用戶端，Lambda 函數必須以[此格式](#api-gateway-simple-proxy-for-lambda-output-format)傳回結果。

 由於 API Gateway 不用在用戶端與後端 Lambda 函數之間介入太多就可進行 Lambda 代理整合，因此用戶端與整合的 Lambda 函數可以根據彼此的變更進行調整，而不需要中斷 API 的現有整合設定。若要啟用這項功能，用戶端必須遵循後端 Lambda 函數所制定的應用程式通訊協定。

 您可以設定任何 API 方法的 Lambda 代理整合。但針對涉及一般代理資源的 API 方法設定時，Lambda 代理整合會更有效。一般代理資源可由 `{proxy+}` 的特殊樣板化路徑變數、catch-all `ANY` 方法預留位置或兩者來表示。用戶端可以在傳入請求中將輸入當作請求參數或適用的承載傳遞到後端 Lambda 函數。這些請求參數包含標頭、URL 路徑變數、查詢字串參數與適用的承載。整合的 Lambda 函數會驗證所有輸入來源，再處理請求，如果遺失所要求的任何輸入，則會以有意義的錯誤訊息來回應用戶端。

 呼叫與 `ANY` 的泛型 HTTP 方法以及 `{proxy+}` 的一般資源整合的 API 方法時，用戶端會以特定 HTTP 方法取代 `ANY` 來提交請求。用戶端也會指定特定 URL 路徑 (而不是 `{proxy+}`)，並包含任何必要的標頭、查詢字串參數或適用的承載。

 下列清單摘要說明不同 API 方法與 Lambda 代理整合的執行時間行為：
+ `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 代理整合中，API Gateway 需要後端 Lambda 函數根據下列 JSON 格式傳回輸出：

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

在輸出中：
+ 如果不再傳回額外的回應標頭，則可以不指定 `headers` 和 `multiValueHeaders` 鍵。
+ `headers` 鍵只能包含單一值標頭。
+ `multiValueHeaders` 鍵可以包含多值標頭以及單一值標頭。您可以使用 `multiValueHeaders` 鍵來指定所有額外標頭，包括任何單一值標頭。
+ 如果您同時指定 `headers` 和 `multiValueHeaders` 的值，API Gateway 會將它們合併成一個清單。如果在兩者指定了相同的鍵值對，則只有 `multiValueHeaders` 中的值會出現在合併清單。

若要啟用 CORS 進行 Lambda 代理整合，您必須將 `Access-Control-Allow-Origin:domain-name` 新增至輸出 `headers`。`domain-name` 可以是 `*`，其代表任何網域名稱。輸出 `body` 會封送處理至前端，以做為方法回應承載。如果 `body` 是二進位 Blob，您可以透過將 `isBase64Encoded` 設定為 `true`將其編碼為 Base64 編碼字串，並將 `*/*` 設定為 **Binary Media Type (二進位媒體類型)**。否則，您可以將它設定為 `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 ..."}` 傳回錯誤，而不擲回例外狀況。

# 使用 設定 API Gateway 的 Lambda 代理整合 AWS CLI
<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 函數的輸入。您可以有更多的自由，讓用戶端傳遞相同的輸入資料。在這裡，用戶端可以傳入接待員名稱以做為查詢字串參數、標頭或內文屬性。此函數也可以支援 Lambda 自訂整合。API 設定較為簡單。您根本不需要設定方法回應或整合回應。

**使用 設定 Lambda 代理整合 AWS CLI**

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)，使用 HTTP 方法 `POST` 進行整合請求。IAM 角色 `apigAwsProxyRole` 的政策必須允許 `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"
   }
   ```

   您可以使用 [add-permission](https://docs.aws.amazon.com/cli/latest/reference/lambda/add-permission.html) 命令來新增資源型許可，而不提供 `credentials` 的 IAM 角色。這就是 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!
   ```

# 使用 Lambda 代理整合與 OpenAPI 定義設定代理資源
<a name="api-gateway-set-up-lambda-proxy-integration-on-proxy-resource"></a>

若要以 Lambda 代理整合類型設定代理資源，請以 Greedy 路徑參數建立 API 資源 (例如 `/parent/{proxy+}`)，並將此資源與 `arn:aws:lambda:us-west-2:123456789012:function:SimpleLambda4ProxyResource` 方法上的 Lambda 函數後端 (例如 `ANY`) 整合。Greedy 路徑參數必須位於 API 資源路徑結尾。如同非代理資源，您可以使用 API Gateway 主控台、匯入 OpenAPI 定義檔，或直接呼叫 API Gateway REST API，來設定代理資源。

下列 OpenAPI API 定義檔顯示 API 範例，其中具有與名為 `SimpleLambda4ProxyResource` 的 Lambda 函數整合的代理資源。

------
#### [ 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 自訂或非代理整合，我們會建立 API Gateway API 來公開 `GET /greeting?greeter={name}` 方法以調用 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>

**使用 設定 Lambda 自訂整合 AWS CLI**

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)，使用 HTTP 方法 `POST` 進行整合請求。`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"
   }
   ```

   IAM 角色 `apigAwsProxyRole` 的政策必須允許 `apigateway` 服務叫用 Lambda 函數。您可以呼叫 [add-permission](https://docs.aws.amazon.com/cli/latest/reference/lambda/add-permission.html) 命令來新增資源型許可，而不提供 `credentials` 的 IAM 角色。這是 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 方法不會傳回結果。

您可以將 Lambda 非代理整合的 Lambda 函數設定為以非同步方式叫用，方法是將 `'Event'` 指定為 [Lambda 叫用類型](https://docs.aws.amazon.com/lambda/latest/dg/lambda-invocation.html)。此作法如下所示：

## 在 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 路徑項目物件](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` 以進行同步呼叫。

## 使用 設定 Lambda 非同步調用 CloudFormation
<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 會傳回兩種錯誤：標準錯誤和自訂錯誤。在您的 API 中，您必須以不同的方式處理它們。

 使用 Lambda 代理整合，Lambda 必須傳回格式如下的輸出：

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

在這個輸出中，`statusCode` 的用戶端錯誤通常是 `4XX`，伺服器錯誤通常是 `5XX`。API Gateway 處理這些錯誤的方法是，根據指定的 `statusCode`，將 Lambda 錯誤映射到 HTTP 錯誤回應。如需 API Gateway 將錯誤類型 (例如 `InvalidParameterException`) 當作回應的一部分傳送到用戶端，Lambda 函數必須在 `headers` 屬性中包含標頭 (例如 `"X-Amzn-ErrorType":"InvalidParameterException"`)。

**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 ..."));
};
```

此函數會傳回下列標準 Lambda 錯誤，包含 `Malformed input ...` 作為錯誤訊息：

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

 同樣地，請考慮下列 Python Lambda 函數，它會引發具有相同 `Malformed input ...` 錯誤訊息的 `Exception`。

```
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 錯誤 Regex**。

**注意**  
API Gateway 使用 Java 模式 regex 進行回應映射。如需詳細資訊，請參閱 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 會根據 `selectionPattern` 屬性規則表達式的模式比對 Lambda 錯誤的 `errorMessage`。若出現相符項目，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*`模式的指定 regex 表達式。



若要使用 API Gateway 主控台設定 `selectionPattern` 表達式，當設定或更新指定的 HTTP 狀態碼的整合回應時，請在 **Lambda 錯誤 Regex** 文字方塊中輸入表達式。

## 處理 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` 物件轉換為 JSON 字串，再呼叫 `callback` 結束函數。否則，`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` 屬性是複雜屬性。它會對應到 `error_trace` 標頭做為 JSON 字串。