在現代 Web 開發中,無伺服器架構已成為主流趨勢。本文將引導讀者使用 AWS API Gateway 和 Lambda 構建高效、可擴充套件的無伺服器 REST API。首先,我們會探討如何設定 API Gateway 呼叫 Lambda 函式所需的許可權,包含使用 aws lambda add-permission 命令的詳細步驟及引數說明。接著,我們將深入研究如何利用 CloudFormation 範本簡化 API 佈署流程,並提供 YAML 格式的範本範例,其中包含關鍵元件如 AWS::ApiGateway::RestApiAWS::ApiGateway::ResourceAWS::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

內容解密:

  1. --function-name:指定要被呼叫的 Lambda 函式名稱。
  2. --statement-id:為該許可權設定一個唯一的識別碼。
  3. --action:指定允許執行的動作,此處為 lambda:InvokeFunction,表示允許呼叫函式。
  4. --principal:指定被授予許可權的 AWS 服務,此處為 apigateway.amazonaws.com,表示 API Gateway。
  5. --source-arn:指定呼叫 Lambda 函式的資源 ARN。此處指定了特定的 API、階段、HTTP 方法和資源路徑。
  6. --profile:指定使用的 AWS 組態檔案。

使用 CloudFormation 範本建立 REST API

現在,讓我們使用 CloudFormation 範本建立 API。我們不會重複討論之前已經涵蓋的步驟或元件。

範本結構

  1. 定義 AWSTemplateFormatVersion 和描述。
  2. 使用 AWS::ApiGateway::RestApi 定義 REST API,並設定 FailOnWarningstrue
  3. 使用 AWS::ApiGateway::Resource 定義資源,路徑部分(PathPart)為 lambdagreeting
  4. lambdagreeting 下,使用 AWS::ApiGateway::Resource 定義路徑引數(PathPart)為 {name}
  5. 使用 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

內容解密:

  1. Type: 指定資源型別為 AWS::ApiGateway::Method
  2. Properties: 定義該方法的屬性。
    • AuthorizationType: 指定授權型別,此處為 NONE,表示無需授權。
    • HttpMethod: 指定 HTTP 方法,此處為 GET
    • Integration: 定義與後端服務的整合。
      • Type: 指定整合型別為 AWS,表示與 AWS 服務整合。
      • IntegrationHttpMethod: 指定 API Gateway 呼叫後端服務使用的 HTTP 方法,此處為 POST
      • IntegrationResponses: 定義整合回應,此處僅包含一個狀態碼為 200 的回應。
      • RequestTemplates: 定義請求範本,用於將客戶端請求資料對映到後端服務所需的格式。
      • Uri: 指定後端服務的呼叫 URI,此處為 Lambda 函式的呼叫 URI,使用 !Sub 函式進行變數替換。
  3. ResourceIdRestApiId: 分別指定該方法所屬的資源和 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 範本進行自動化佈署。主要涉及以下幾個關鍵點:

  1. Lambda 許可權組態: 使用 aws lambda add-permission 命令賦予 API Gateway 呼叫 Lambda 的許可權。
  2. CloudFormation 範本: 使用 YAML 或 JSON 格式的範本定義 REST API、資源、方法和整合。
  3. 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 範本元件解析

如同以往,我們會從範本版本和描述開始。對於 RestApiResourceDeployment 等資源型別,其選項並未有太大變化。輸出的部分也與之前相同。在方法宣告中,我們使用了 AWS 整合型別,以及所需的 URI 格式。

在管理控制檯中,您可以選擇單獨的 Lambda 整合選項和 AWS 整合選項。然而,在使用 CLI 命令和 CloudFormation 範本時,兩種情況都使用 AWS 整合選項。

重點技術解析

我們引入了一個新的內建函式:Fn::ImportValueFn::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 命令解析

  1. 使用 aws apigateway create-rest-api 子命令建立 REST API。
  2. 使用 aws apigateway get-resources 子命令取得 API 的根資源(/)。
  3. 使用 aws apigateway create-resource 子命令建立路徑部分 lambdagreeting
  4. 使用 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”,表示不需要授權。
  1. 使用 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。
  1. 使用 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。
  1. 使用 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:選擇模式,本例中為空字串,表示匹配所有回應。
  1. 使用 aws apigateway create-deployment 子命令,將 API 佈署到階段 dev
  2. 使用 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 資源。