在現代 Web 開發中,無伺服器架構已成為主流趨勢。本文將引導讀者使用 AWS API Gateway 和 Lambda 構建高效、可擴充套件的無伺服器 REST API。首先,我們會探討如何設定 API Gateway 呼叫 Lambda 函式所需的許可權,包含使用 aws lambda add-permission 命令的詳細步驟及引數說明。接著,我們將深入研究如何利用 CloudFormation 範本簡化 API 佈署流程,並提供 YAML 格式的範本範例,其中包含關鍵元件如 AWS::ApiGateway::RestApi、AWS::ApiGateway::Resource 和 AWS::ApiGateway::Method 的使用方法。同時,我們也會示範如何使用 CLI 命令逐步建立 REST API,包含定義資源、方法、整合以及佈署等操作。
使用 API Gateway 建置無伺服器 REST API - 第 2 章
賦予 API 呼叫 Lambda 的許可權
要允許 API Gateway 呼叫 Lambda 函式,需要使用 aws lambda add-permission 命令新增相應的許可權。範例如下:
aws lambda add-permission \
--function-name lambda-for-api-gateway \
--statement-id apigateway-st-1 \
--action lambda:InvokeFunction \
--principal apigateway.amazonaws.com \
--source-arn "arn:aws:execute-api:us-east-1:<account_id>:tyu4dw36th/dev/GET/lambdagreeting/{name}" \
--profile admin
內容解密:
--function-name:指定要被呼叫的 Lambda 函式名稱。--statement-id:為該許可權設定一個唯一的識別碼。--action:指定允許執行的動作,此處為lambda:InvokeFunction,表示允許呼叫函式。--principal:指定被授予許可權的 AWS 服務,此處為apigateway.amazonaws.com,表示 API Gateway。--source-arn:指定呼叫 Lambda 函式的資源 ARN。此處指定了特定的 API、階段、HTTP 方法和資源路徑。--profile:指定使用的 AWS 組態檔案。
使用 CloudFormation 範本建立 REST API
現在,讓我們使用 CloudFormation 範本建立 API。我們不會重複討論之前已經涵蓋的步驟或元件。
範本結構
- 定義
AWSTemplateFormatVersion和描述。 - 使用
AWS::ApiGateway::RestApi定義 REST API,並設定FailOnWarnings為true。 - 使用
AWS::ApiGateway::Resource定義資源,路徑部分(PathPart)為lambdagreeting。 - 在
lambdagreeting下,使用AWS::ApiGateway::Resource定義路徑引數(PathPart)為{name}。 - 使用
AWS::ApiGateway::Method定義 HTTP 方法為 GET,並設定 AWS 整合型別和對應的 Lambda 整合 URI。
範例程式碼如下:
MyMethod:
Type: AWS::ApiGateway::Method
Properties:
AuthorizationType: NONE
HttpMethod: GET
Integration:
Type: AWS
IntegrationHttpMethod: POST
IntegrationResponses:
- StatusCode: 200
RequestTemplates:
application/json: "{\"name\": \"$input.params('name')\" , \"time\": \"$input.params('time')\"}"
Uri: !Sub
- 'arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/arn:aws:lambda:us-east-1:${AWS::AccountId}:function:${LAMBDA_NAME}/invocations'
- LAMBDA_NAME: !ImportValue LambdaForApiGateway
ResourceId: !Ref NamePathParamResource
RestApiId: !Ref MyRestAPI
MethodResponses:
- StatusCode: 200
內容解密:
Type: 指定資源型別為AWS::ApiGateway::Method。Properties: 定義該方法的屬性。AuthorizationType: 指定授權型別,此處為NONE,表示無需授權。HttpMethod: 指定 HTTP 方法,此處為GET。Integration: 定義與後端服務的整合。Type: 指定整合型別為AWS,表示與 AWS 服務整合。IntegrationHttpMethod: 指定 API Gateway 呼叫後端服務使用的 HTTP 方法,此處為POST。IntegrationResponses: 定義整合回應,此處僅包含一個狀態碼為 200 的回應。RequestTemplates: 定義請求範本,用於將客戶端請求資料對映到後端服務所需的格式。Uri: 指定後端服務的呼叫 URI,此處為 Lambda 函式的呼叫 URI,使用!Sub函式進行變數替換。
ResourceId和RestApiId: 分別指定該方法所屬的資源和 REST API。
呼叫 API
完成上述組態後,可以透過瀏覽器呼叫 API,URL 格式如下:
https://tyu4dw36th.execute-api.us-east-1.amazonaws.com/dev/lambdagreeting/Heartin
或帶有查詢引數:
https://tyu4dw36th.execute-api.us-east-1.amazonaws.com/dev/lambdagreeting/Heartin?time=Morning
重點解析
本文主要介紹瞭如何使用 API Gateway 與 Lambda 整合構建無伺服器 REST API,並透過 CloudFormation 範本進行自動化佈署。主要涉及以下幾個關鍵點:
- Lambda 許可權組態: 使用
aws lambda add-permission命令賦予 API Gateway 呼叫 Lambda 的許可權。 - CloudFormation 範本: 使用 YAML 或 JSON 格式的範本定義 REST API、資源、方法和整合。
- API 呼叫: 透過瀏覽器或其他客戶端呼叫佈署好的 API。
Plantuml 圖示說明此架構流程
@startuml
skinparam backgroundColor #FEFEFE
skinparam defaultTextAlignment center
skinparam rectangleBackgroundColor #F5F5F5
skinparam rectangleBorderColor #333333
skinparam arrowColor #333333
title Plantuml 圖示說明此架構流程
rectangle "HTTP Request" as node1
rectangle "Invoke" as node2
rectangle "處理請求" as node3
rectangle "HTTP Response" as node4
node1 --> node2
node2 --> node3
node3 --> node4
@enduml此圖示說明瞭客戶端透過 API Gateway 呼叫 Lambda 函式的流程。客戶端發起 HTTP 請求到 API Gateway,API Gateway 呼叫對應的 Lambda 函式處理請求,並將結果傳回給客戶端。
使用 API Gateway 建置無伺服器 REST APIs 第二章
CloudFormation 範本元件解析
如同以往,我們會從範本版本和描述開始。對於 RestApi、Resource 和 Deployment 等資源型別,其選項並未有太大變化。輸出的部分也與之前相同。在方法宣告中,我們使用了 AWS 整合型別,以及所需的 URI 格式。
在管理控制檯中,您可以選擇單獨的 Lambda 整合選項和 AWS 整合選項。然而,在使用 CLI 命令和 CloudFormation 範本時,兩種情況都使用 AWS 整合選項。
重點技術解析
我們引入了一個新的內建函式:Fn::ImportValue。Fn::ImportValue 用於取得另一個堆積疊(在本例中為 Lambda 堆積疊)輸出的值。匯出和匯入僅允許在區域內進行,且匯出名稱在區域內必須是唯一的。
此外,我們使用了新的型別 AWS::Lambda::Permission,為 Lambda 新增許可權。其選項與我們使用的 CLI 命令類別似,但我們使用了 CloudFormation 內建函式和變數,以避免硬編碼。在處理 API Gateway 時,您只需要使用 SourceArn 指定 SourceAccount。然而,如果您指定的是資源(例如 S3 儲存桶),則還需要指定 SourceAccount 選項。
建置和測試第一個 POST API 方法
在本章節中,我們將建立一個簡單的 POST API 方法,該方法具有與 Lambda 的 AWS 整合。REST 客戶端將以 Lambda 所需的格式向 API 方法傳送 JSON 請求主體,並將其傳遞給 Lambda。我們將重用上一章節中的 Lambda。
準備工作
您需要一個有效的 AWS 賬戶。您需要按照第一章節中的指示,設定 Java、Maven、父專案 serverless-cookbook-parent-aws-java 和 AWS CLI。此外,您可能還需要閱讀其他相關的注意事項,包括程式碼使用、S3 儲存桶建立和 Windows 使用者的注意事項。
由於我們重用了上一章節中的 Lambda,因此您需要使用其 CloudFormation 範本構建和佈署該 Lambda(如果尚未佈署)。您可以按照該章節中的步驟構建和上傳 JAR 到 S3,並使用提供的 CloudFormation 範本佈署 Lambda。
使用 CLI 命令建立 API
首先,我們將使用 AWS CLI 命令建立 REST API。我們不會展示已經在之前章節中討論過的命令。然而,完整的命令將在程式碼檔案中提供。
CLI 命令解析
- 使用
aws apigateway create-rest-api子命令建立 REST API。 - 使用
aws apigateway get-resources子命令取得 API 的根資源(/)。 - 使用
aws apigateway create-resource子命令建立路徑部分lambdagreeting。 - 使用
aws apigateway put-method命令,指定 HTTP 方法為 POST,如下所示:
aws apigateway put-method \
--rest-api-id 7uwav24q1f \
--resource-id s6rij6 \
--http-method POST \
--authorization-type "NONE" \
--region us-east-1 \
--profile admin
內容解密:
此命令用於為指定的資源建立一個新的方法。引數說明如下:
--rest-api-id:REST API 的 ID。--resource-id:資源的 ID。--http-method:HTTP 方法,本例中為 POST。--authorization-type:授權型別,本例中為 “NONE”,表示不需要授權。
- 使用
aws apigateway put-method-response命令,指定狀態碼為 200,如下所示:
aws apigateway put-method-response \
--rest-api-id 7uwav24q1f \
--resource-id s6rij6 \
--http-method POST \
--status-code 200 \
--region us-east-1 \
--profile admin
內容解密:
此命令用於為指定的方法建立一個新的回應。引數說明如下:
--rest-api-id和--resource-id與上一步相同。--http-method:HTTP 方法,本例中為 POST。--status-code:HTTP 狀態碼,本例中為 200。
- 使用
aws apigateway put-integration命令,指定 HTTP 方法為 POST,型別為 AWS,並提供 Lambda URI,如下所示:
aws apigateway put-integration \
--rest-api-id 7uwav24q1f \
--resource-id s6rij6 \
--http-method POST \
--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:<account_id>:function:lambda-for-api-gateway/invocations' \
--region us-east-1 \
--profile admin
內容解密:
此命令用於為指定的方法建立一個新的整合。引數說明如下:
--rest-api-id、--resource-id和--http-method與上一步相同。--type:整合型別,本例中為 AWS,表示與 AWS 服務整合。--integration-http-method:整合的 HTTP 方法,本例中為 POST。--uri:Lambda 函式的呼叫 URI。
- 使用
aws apigateway put-integration-response命令,指定選擇模式為 “",如下所示:
aws apigateway put-integration-response \
--rest-api-id 7uwav24q1f \
--resource-id s6rij6 \
--http-method POST \
--status-code 200 \
--region us-east-1 \
--selection-pattern "" \
--profile admin
內容解密:
此命令用於為指定的整合建立一個新的回應。引數說明如下:
--rest-api-id、--resource-id和--http-method與上一步相同。--status-code:HTTP 狀態碼,本例中為 200。--selection-pattern:選擇模式,本例中為空字串,表示匹配所有回應。
- 使用
aws apigateway create-deployment子命令,將 API 佈署到階段dev。 - 使用
aws lambda add-permission命令,為 API 新增呼叫 Lambda 的許可權,如下所示:
aws lambda add-permission \
--function-name lambda-for-api-gateway \
--statement-id apigateway-st-2 \
--action lambda:InvokeFunction \
--principal apigateway.amazonaws.com \
--source-arn "arn:aws:execute-api:us-east-1:<account_id>:7uwav24q1f/*/POST/lambdagreeting" \
--profile admin
內容解密:
此命令用於為 Lambda 函式新增呼叫許可權。引數說明如下:
--function-name:Lambda 函式的名稱。--statement-id:宣告 ID,用於唯一標識此許可權宣告。--action:允許的操作,本例中為lambda:InvokeFunction,表示允許呼叫 Lambda 函式。--principal:主體,本例中為apigateway.amazonaws.com,表示允許 API Gateway 呼叫 Lambda 函式。--source-arn:源 ARN,用於指定允許呼叫 Lambda 的 API Gateway 資源。