

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

# 使用 Amazon API Gateway 端點調用 Lambda 函數
<a name="services-apigateway"></a>

您可以使用 Amazon API Gateway 為您的 Lambda 函數建立具有 HTTP 端點的 Web API。API Gateway 提供了用於建立和記錄 Web API 的工具，可將 HTTP 請求路由至 Lambda 函數。您可以使用身分驗證和授權控制來保護對 API 的存取。您的 API 可以透過網際網路提供流量，也可以只在 VPC 內存取。

**提示**  
Lambda 提供兩種透過 HTTP 端點調用函數的方式：API Gateway 與 Lambda 函數 URL。如果不確定哪種方法最適合自己的使用案例，請參閱[選取一種使用 HTTP 請求調用 Lambda 函數的方法](apig-http-invoke-decision.md)。

API 中的資源定義一個或多個方法，例如 GET 或 POST。方法具有將請求路由到 Lambda 函數或其他整合類型的整合。您可以個別定義每個資源和方法，或使用特殊資源和方法類型來比對所有符合某模式的請求。[代理資源](https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-lambda-proxy-integrations.html)會擷取資源下的所有路徑。`ANY` 方法會擷取所有 HTTP 方法。

**Topics**
+ [選擇 API 類型](#services-apigateway-apitypes)
+ [將端點新增至您的 Lambda 函數](#apigateway-add)
+ [Proxy 整合](#apigateway-proxy)
+ [事件格式](#apigateway-example-event)
+ [回應格式](#apigateway-types-transforms)
+ [許可](#apigateway-permissions)
+ [範例應用程式](#services-apigateway-samples)
+ [Powertools for AWS Lambda 的事件處理常式](#services-apigateway-powertools)
+ [教學課程：搭配使用 Lambda 與 API Gateway](services-apigateway-tutorial.md)
+ [使用 API Gateway API 處理 Lambda 錯誤](services-apigateway-errors.md)
+ [選取一種使用 HTTP 請求調用 Lambda 函數的方法](apig-http-invoke-decision.md)

## 選擇 API 類型
<a name="services-apigateway-apitypes"></a>

API Gateway 支援三種調用 Lambda 函數的 API 類型：
+ [HTTP API](https://docs.aws.amazon.com/apigateway/latest/developerguide/http-api.html)：輕量型的低延遲 RESTful API。
+ [REST API](https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-rest-api.html)：功能豐富的可自訂 RESTful API。
+ [WebSocket API](https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-websocket-api.html)：與用戶端維持持續連線以進行全雙工通訊的 Web API。

HTTP API 和 REST API 都是處理 HTTP 請求並傳回回應的 RESTful API。HTTP API 較新，並且是使用 API Gateway 版本 2 API 建置而成。下列功能是 HTTP API 的新功能：

**HTTP API 功能**
+ **自動部署** - 當您修改路由或整合時，變更會自動部署至已啟用自動部署的階段。
+ **預設階段** - 您可以建立預設階段 (`$default`)，在 API URL 的根路徑提供請求。對於具名階段，您必須在路徑的開頭加入階段名稱。
+ **CORS 組態** - 您可以設定 API 將 CORS 標頭新增到傳出回應中，而不是在函數程式碼中手動新增。

REST API 是 API Gateway 自推出以來支援的典型 RESTful API。REST API 目前具有更多的自訂、整合和管理功能。

**REST API 功能**
+ **整合類型** - REST API 支援自訂 Lambda 整合。您可以使用自訂整合，只將請求的本文傳送到函數，或者在將請求本文傳送到函數之前套用轉換範本。
+ **存取控制** - REST API 支援其他身分驗證和授權選項。
+ **監控和追蹤** – REST APIs支援 AWS X-Ray 追蹤和其他記錄選項。

如需詳細比較，請參閱《API Gateway 開發人員指南》**中的 [Choose between HTTP APIs and REST APIs](https://docs.aws.amazon.com/apigateway/latest/developerguide/http-api-vs-rest.html)。

WebSocket API 也使用 API Gateway 版本 2 API，並支援類似的功能集。對於可從用戶端與 API 之間持續連線獲益的應用程式，請使用 WebSocket API。WebSocket API 提供全雙工通訊，這意味著用戶端和 API 都可以連續傳送訊息，而無需等待回應。

HTTP API 支援簡化的事件格式 (2.0 版)。如需 HTTP API 事件的範例，請參閱[在 API Gateway 中建立 HTTP APIs AWS Lambda 代理整合](https://docs.aws.amazon.com//apigateway/latest/developerguide/http-api-develop-integrations-lambda.html)。

如需詳細資訊，請參閱[在 API Gateway 中建立 HTTP APIs AWS Lambda 代理整合](https://docs.aws.amazon.com/apigateway/latest/developerguide/http-api-develop-integrations-lambda.html)。

## 將端點新增至您的 Lambda 函數
<a name="apigateway-add"></a>

**若要將公有端點新增至您的 Lambda 函數**

1. 開啟 Lambda 主控台中的 [函數頁面](https://console.aws.amazon.com/lambda/home#/functions)。

1. 選擇一個函數。

1. 在**函數概觀**下，選擇**新增觸發條件**。

1. 選取 **API Gateway** (API Gateway )。

1. 選擇 **Create an API** (建立 API) 或 **Use an existing API** (使用現有 API)。

   1. **全新 API**：對於 **API type** (API 類型)，請選擇 **HTTP API**。如需詳細資訊，請參閱[選擇 API 類型](#services-apigateway-apitypes)。

   1. **現有 API：**從下拉式清單中選取 API 或輸入 API ID (例如，r3pmxmplak)。

1. 在 **Security** (安全性) 中，選擇 **Open** (開啟)。

1. 選擇 **Add** (新增)。

## Proxy 整合
<a name="apigateway-proxy"></a>

API Gateway API 由階段、資源、方法和整合所組成。階段和資源決定端點的路徑：

**API 路徑格式**
+ `/prod/` - `prod` 階段和根資源。
+ `/prod/user` - `prod` 階段和 `user` 資源。
+ `/dev/{proxy+}` - `dev` 階段中的任何路由。
+ `/` - (HTTP API) 預設階段和根資源。

Lambda 整合將路徑和 HTTP 方法組合映射到一個 Lambda 函數。您可以設定 API Gateway 依現狀傳遞 HTTP 請求的主體 (自訂整合)，或將請求主體封裝在一個包含所有請求資訊 (包括標頭、資源、路徑和方法) 的文件中。

如需設定詳細資訊，請參閱 [Lambda proxy integrations in API Gateway](https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-lambda-proxy-integrations.html)。

## 事件格式
<a name="apigateway-example-event"></a>

Amazon API Gateway 使用包含 HTTP 請求之 JSON 表示的事件來[同步](invocation-sync.md)調用您的函數。對於自訂整合，事件是請求的本文。對於代理整合，事件具有已定義的結構。如需 API Gateway REST API 的代理事件範例，請參閱《API Gateway 開發人員指南》**中的[代理整合之 Lambda 函數的輸入格式](https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-lambda-proxy-integrations.html#api-gateway-simple-proxy-for-lambda-input-format)。

## 回應格式
<a name="apigateway-types-transforms"></a>

API Gateway 會等待函數的回應並將結果轉達給呼叫者。對於自訂整合，您可以定義整合回應和方法回應，將函數的輸出轉換為 HTTP 回應。對於代理整合，函數必須以特定格式的回應表示作出回應。

下列範例顯示來自 Node.js 函數的回應物件。回應物件表示包含 JSON 文件的成功 HTTP 回應。

**Example index.mjs - 代理整合回應物件 (Node.js)**  

```
var response = {
      "statusCode": 200,
      "headers": {
        "Content-Type": "application/json"
      },
      "isBase64Encoded": false,
      "multiValueHeaders": { 
        "X-Custom-Header": ["My value", "My other value"],
      },
      "body": "{\n  \"TotalCodeSize\": 104330022,\n  \"FunctionCount\": 26\n}"
    }
```

Lambda 執行時間會將回應物件序列化為 JSON，並將其傳送至 API。API 會剖析該回應並用它來建立 HTTP 回應，然後將其傳送到發出原始請求的用戶端。

**Example HTTP 回應**  

```
< HTTP/1.1 200 OK
  < Content-Type: application/json
  < Content-Length: 55
  < Connection: keep-alive
  < x-amzn-RequestId: 32998fea-xmpl-4268-8c72-16138d629356
  < X-Custom-Header: My value
  < X-Custom-Header: My other value
  < X-Amzn-Trace-Id: Root=1-5e6aa925-ccecxmplbae116148e52f036
  <
  {
    "TotalCodeSize": 104330022,
    "FunctionCount": 26
  }
```

## 許可
<a name="apigateway-permissions"></a>

Amazon API Gateway 會取得許可，從函數的[以資源為基礎的政策](access-control-resource-based.md)中調用您的函數。您可以將呼叫許可授與整個 API，或將有限存取權授與階段、資源或方法。

當您透過使用 Lambda 主控台、使用 API Gateway 主控台或在 AWS SAM 範本中，將 API 新增至函數時，會自動更新函數的以資源為基礎的政策。範例函數政策範例如下。

**Example 函數政策**    
****  

```
{
  "Version":"2012-10-17",		 	 	 
  "Id": "default",
  "Statement": [
    {
      "Sid": "nodejs-apig-functiongetEndpointPermissionProd-BWDBXMPLXE2F",
      "Effect": "Allow",
      "Principal": {
        "Service": "apigateway.amazonaws.com"
      },
      "Action": "lambda:InvokeFunction",
      "Resource": "arn:aws:lambda:us-east-2:{{111122223333}}:function:nodejs-apig-function-1G3MXMPLXVXYI",
      "Condition": {
        "StringEquals": {
          "aws:SourceAccount": "111122223333"
        },
        "ArnLike": {
          "aws:SourceArn": "arn:aws:execute-api:us-east-2:{{111122223333}}:ktyvxmpls1/*/GET/"
        }
      }
    }
  ]
}
```

您可以使用下列 API 操作來手動管理函數政策許可：
+ [AddPermission](https://docs.aws.amazon.com/lambda/latest/api/API_AddPermission.html)
+ [RemovePermission](https://docs.aws.amazon.com/lambda/latest/api/API_RemovePermission.html)
+ [GetPolicy](https://docs.aws.amazon.com/lambda/latest/api/API_GetPolicy.html)

若要將調用許可授與現有 API，請使用 `add-permission` 命令。範例：

```
aws lambda add-permission \
  --function-name my-function \
  --statement-id apigateway-get --action lambda:InvokeFunction \
  --principal apigateway.amazonaws.com \
  --source-arn "arn:aws:execute-api:us-east-2:123456789012:mnh1xmpli7/default/GET/"
```

您應該會看到下列輸出：

```
{
    "Statement": "{\"Sid\":\"apigateway-test-2\",\"Effect\":\"Allow\",\"Principal\":{\"Service\":\"apigateway.amazonaws.com\"},\"Action\":\"lambda:InvokeFunction\",\"Resource\":\"arn:aws:lambda:us-east-2:123456789012:function:my-function\",\"Condition\":{\"ArnLike\":{\"AWS:SourceArn\":\"arn:aws:execute-api:us-east-2:123456789012:mnh1xmpli7/default/GET\"}}}"
}
```

**注意**  
如果您的函數和 API 位於不同的 中 AWS 區域，來源 ARN 中的區域識別符必須符合函數的區域，而不是 API 的區域。當 API Gateway 調用函數時，它會使用以 API 的 ARN 為基礎的資源 ARN，但會加以修改以符合函數的區域。

此範例中的來源 ARN 會將許可授與 API 的預設階段中根資源 GET 方法的整合 (ID 為 `mnh1xmpli7`)。您可以在來源 ARN 中使用星號，將許可授與多個階段、方法或資源。

**資源模式**
+ `mnh1xmpli7/*/GET/*` - 所有階段中所有資源上的 GET 方法。
+ `mnh1xmpli7/prod/ANY/user` - `prod` 階段中 `user` 資源上的 ANY 方法。
+ `mnh1xmpli7/*/*/*` - 所有階段中所有資源上的任何方法。

如需檢視政策和移除陳述式的詳細資訊，請參閱 [在 Lambda 中檢視資源型 IAM 政策](access-control-resource-based.md)。

## 範例應用程式
<a name="services-apigateway-samples"></a>

[具有 Node.js 的 API Gateway](https://github.com/awsdocs/aws-lambda-developer-guide/tree/main/sample-apps/nodejs-apig) 範例應用程式包含具有 範本的 AWS SAM 函數，該範本會建立已啟用 AWS X-Ray 追蹤的 REST API。它也包括用於部署、調用函數、測試 API 和清理的指令碼。

## Powertools for AWS Lambda 的事件處理常式
<a name="services-apigateway-powertools"></a>

撰寫 API Gateway 端點 (HTTP 或 REST) 調用的 Lambda 函數時，來自 Powertools for AWS Lambda 工具組的事件處理常式提供路由、中介軟體、CORS 組態、OpenAPI 規格產生、請求驗證、錯誤處理和其他實用功能。該事件處理常式公用程式適用於 Python 與 TypeScript/JavaScript。如需詳細資訊，請參閱 *Powertools for AWS Lambda (Python) 文件*中的[事件處理常式 REST API](https://docs.powertools.aws.dev/lambda/python/latest/core/event_handler/api_gateway/)，以及 *Powertools for AWS Lambda (TypeScript) 文件*中的[事件處理常式 HTTP API](https://docs.aws.amazon.com/powertools/typescript/latest/features/event-handler/http/)。

### Python
<a name="services-apigateway-powertools-python"></a>

```
from aws_lambda_powertools import Logger
from aws_lambda_powertools.event_handler import APIGatewayRestResolver
from aws_lambda_powertools.logging import correlation_paths
from aws_lambda_powertools.utilities.typing.lambda_context import LambdaContext

app = APIGatewayRestResolver()
logger = Logger()

@app.get("/healthz")
def ping():
    return {"message": "health status ok"}

@logger.inject_lambda_context(correlation_id_path=correlation_paths.API_GATEWAY_REST)  
def lambda_handler(event: dict, context: LambdaContext) -> dict:
    return app.resolve(event, context)
```

### Typescript
<a name="services-apigateway-powertools-typescript"></a>

```
import { Router } from '@aws-lambda-powertools/event-handler/experimental-rest';
import { Logger } from '@aws-lambda-powertools/logger';
import {
  correlationPaths,
  search,
} from '@aws-lambda-powertools/logger/correlationId';
import type { Context } from 'aws-lambda/handler';

const logger = new Logger({
  correlationIdSearchFn: search,
});

const app = new Router({ logger });

app.get("/healthz", async () => {
  return { message: "health status ok" };
});

export const handler = async (event: unknown, context: Context) => {
  // You can continue using other utilities just as before
  logger.addContext(context);
  logger.setCorrelationId(event, correlationPaths.API_GATEWAY_REST);
  return app.resolve(event, context);
};
```