搭配使用 AWS Lambda 與 Amazon API Gateway - AWS Lambda

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

搭配使用 AWS Lambda 與 Amazon API Gateway

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

API 中的資源定義一個或多個方法,例如 GET 或 POST。方法具有將請求路由到 Lambda 函數或其他整合類型的整合。您可以個別定義每個資源和方法,或使用特殊資源和方法類型來比對所有符合某模式的請求。代理資源會擷取資源下的所有路徑。ANY 方法會擷取所有 HTTP 方法。

本節說明如何選擇 API 類型、將端點新增至 Lambda 函數,以及事件、許可、回應和錯誤處理的相關一般資訊。

將端點新增至您的 Lambda 函數

若要將公有端點新增至您的 Lambda 函數
  1. 開啟 Lambda 主控台中的 函數頁面

  2. 選擇一個函數。

  3. 函式概觀 下,選擇 新增觸發條件

  4. 選取 API Gateway (API Gateway )。

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

    1. 全新 API:對於 API type (API 類型),請選擇 HTTP API。如需詳細資訊,請參閱 API 類型

    2. 現有 API:從下拉式選單中選取 API 或輸入 API ID (例如,r3pmxmplak)。

  6. Security (安全性) 中,選擇 Open (開啟)。

  7. 選擇 Add (新增)。

代理整合

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

API 路徑格式
  • /prod/ - prod 階段和根資源。

  • /prod/user - prod 階段和 user 資源。

  • /dev/{proxy+} - dev 階段中的任何路由。

  • / - (HTTP API) 預設階段和根資源。

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

事件格式

Amazon API Gateway 使用包含 HTTP 請求之 JSON 表示的事件來同步調用您的函數。對於自訂整合,事件是請求的本文。對於代理整合,事件具有已定義的結構。下列範例顯示來自 API Gateway REST API 的代理事件。

範例 event.json API Gateway 代理事件 (REST API)
{ "resource": "/", "path": "/", "httpMethod": "GET", "requestContext": { "resourcePath": "/", "httpMethod": "GET", "path": "/Prod/", ... }, "headers": { "accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9", "accept-encoding": "gzip, deflate, br", "Host": "70ixmpl4fl.execute-api.us-east-2.amazonaws.com", "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Safari/537.36", "X-Amzn-Trace-Id": "Root=1-5e66d96f-7491f09xmpl79d18acf3d050", ... }, "multiValueHeaders": { "accept": [ "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9" ], "accept-encoding": [ "gzip, deflate, br" ], ... }, "queryStringParameters": null, "multiValueQueryStringParameters": null, "pathParameters": null, "stageVariables": null, "body": null, "isBase64Encoded": false }

回應格式

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

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

範例 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 回應,然後將其傳送到發出原始請求的用戶端。

範例 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 }

許可

Amazon API Gateway 會取得許可,從函數的以資源為基礎的政策中調用您的函數。您可以將呼叫許可授與整個 API,或將有限存取權授與階段、資源或方法。

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

範例 函數政策
{ "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 操作來手動管理函數政策許可:

若要將調用許可授與現有 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 位於不同區域,則來源 ARN 中的區域識別符必須符合函式的區域,而不是 API 的區域。當 API Gateway 調用函數時,它會使用以 API 的 ARN 為基礎的資源 ARN,但會加以修改以符合函數的區域。

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

資源模式
  • mnh1xmpli7/*/GET/* - 所有階段中所有資源上的 GET 方法。

  • mnh1xmpli7/prod/ANY/user - prod 階段中 user 資源上的 ANY 方法。

  • mnh1xmpli7/*/*/* - 所有階段中所有資源上的任何方法。

如需檢視政策和移除陳述式的詳細資訊,請參閱 清理以資源為基礎的政策

使用 API Gateway API 處理錯誤

API Gateway 會將所有調用和函數錯誤視為內部錯誤。如果 Lambda API 拒絕調用請求,則 API Gateway 會傳回 500 錯誤代碼。如果函數執行但傳回錯誤,或傳回格式錯誤的回應,API Gateway 會傳回 502。在這兩種情況下,API Gateway 的回應主體為 {"message": "Internal server error"}

注意

API Gateway 不會重試任何 Lambda 調用。如果 Lambda 傳回錯誤,API Gateway 會將錯誤回應傳回至用戶端。

下列範例顯示導致函數錯誤和 API Gateway 傳回 502 的請求的 X-Ray 流程圖。用戶端會收到一般錯誤訊息。


        透過 API Gateway 處理函數錯誤的流程圖。

若要自訂錯誤回應,您必須在程式碼中發現錯誤,並以必要的格式格式化回應。

範例 index.mjs - 格式錯誤
var formatError = function(error){ var response = { "statusCode": error.statusCode, "headers": { "Content-Type": "text/plain", "x-amzn-ErrorType": error.code }, "isBase64Encoded": false, "body": error.code + ": " + error.message } return response }

API Gateway 將此回應轉換為具有自定義狀態碼和主體的 HTTP 錯誤。在流程圖中,函數節點是綠色的,因為它會處理錯誤。


        透過 API Gateway 處理格式化錯誤的流程圖。

選擇 API 類型

API Gateway 支援三種調用 Lambda 函數的 API 類型:

  • HTTP API - 輕量型、低延遲 RESTful API。

  • REST API - 功能豐富的可自訂 RESTful API。

  • WebSocket API — 一種 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 API 支援 AWS X-Ray 追蹤和其他記錄選項。

如需詳細比較,請參閱 API Gateway 開發人員指南中的在 HTTP API 和 REST API 之間選擇

WebSocket API 也會使用 API Gateway 第 2 版 API,並支援類似的功能集。針對受益於用戶端和 WebSocket API 之間持續連線的應用程式使用 API。 WebSocket API 提供全雙工通訊,這表示用戶端和 API 都可以連續傳送訊息,而無需等待回應。

HTTP API 支援簡化的事件格式 (2.0 版)。下列範例顯示來自 HTTP API 的事件。

範例 event-v2.json - API Gateway 代理事件 (HTTP API)
{ "version": "2.0", "routeKey": "ANY /nodejs-apig-function-1G3XMPLZXVXYI", "rawPath": "/default/nodejs-apig-function-1G3XMPLZXVXYI", "rawQueryString": "", "cookies": [ "s_fid=7AABXMPL1AFD9BBF-0643XMPL09956DE2", "regStatus=pre-register" ], "headers": { "accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9", "accept-encoding": "gzip, deflate, br", ... }, "requestContext": { "accountId": "123456789012", "apiId": "r3pmxmplak", "domainName": "r3pmxmplak.execute-api.us-east-2.amazonaws.com", "domainPrefix": "r3pmxmplak", "http": { "method": "GET", "path": "/default/nodejs-apig-function-1G3XMPLZXVXYI", "protocol": "HTTP/1.1", "sourceIp": "205.255.255.176", "userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Safari/537.36" }, "requestId": "JKJaXmPLvHcESHA=", "routeKey": "ANY /nodejs-apig-function-1G3XMPLZXVXYI", "stage": "default", "time": "10/Mar/2020:05:16:23 +0000", "timeEpoch": 1583817383220 }, "isBase64Encoded": true }

如需詳細資訊,請參閱《API Gateway 開發人員指南》中的 AWS Lambda 整合

範例應用程式

本指南的 GitHub 儲存庫提供下列 API Gateway 的範例應用程式。

  • 具有 Node.js 的 API Gateway - 具有 AWS SAM 範本的函數,該函數可建立已啟用 AWS X-Ray 追蹤的 REST API。它包括用於部署、調用函數、測試 API 和清理的指令碼。

Lambda 還提供藍圖範本,供您用於 Lambda 主控台中建立 API Gateway 應用程式。