教學課程:建立具有兩個 AWS 服務整合和一個 Lambda 非代理整合的計算器 REST API - Amazon API 网关

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

教學課程:建立具有兩個 AWS 服務整合和一個 Lambda 非代理整合的計算器 REST API

專門教學課程:使RESTAPI用 Lambda 非代理整合建立使用Lambda Function集成。 Lambda Function整合是整合類型的特殊案例,可為您執行大部分整合設定,例如自動新增所需的以資源為基礎的權限以呼叫 Lambda 函數。AWS Service在這裡,三種整合中的兩種會使用 AWS Service 整合。在此整合類型中,您具有更多的控制,但需要手動執行任務,像是建立和指定 IAM 角色,其中包含適當的許可。

在本教學課程中,您將需要建立 Calc Lambda 函數來實作基本算術運算,並接受和傳回 JSON 格式的輸入和輸出。然後,您將建立一個 REST API,並使用下列方式將其與 Lambda 函數整合:

  1. GET 資源上公開 /calc 方法來叫用 Lambda 函數,並提供輸入做為查詢字串參數。(AWS Service 整合)

  2. POST 資源上公開 /calc 方法來叫用 Lambda 函數,並在方法請求酬載中提供輸入。(AWS Service 整合)

  3. 在巢狀 GET 資源上公開 /calc/{operand1}/{operand2}/{operator} 來叫用 Lambda 函數,並提供輸入做為路徑參數 (Lambda Function 整合)

除了試做本教學課程之外,您可能還想要研究 Calc API 的 OpenAPI 定義檔,您可以依照 RESTAPIs使用 API「在API閘道開啟」開發 中的指示,將此定義檔匯入至 API Gateway。

建立可擔任的 IAM 角色

為了讓 API 叫用 Calc Lambda 函數,您將需要具有 API Gateway 可擔任的 IAM 角色,這是具有以下信任關係的 IAM 角色:

{ "Version": "2012-10-17", "Statement": [ { "Sid": "", "Effect": "Allow", "Principal": { "Service": "apigateway.amazonaws.com" }, "Action": "sts:AssumeRole" } ] }

您建立的角色必須具有 Lambda InvokeFunction權限。否則,API 發起人將會收到 500 Internal Server Error 回應。若要將此許可給與角色,請將下列 IAM 政策連接至其中:

{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "lambda:InvokeFunction", "Resource": "*" } ] }

以下是如何完成此全部操作的方式:

建立 API Gateway 可擔任的 IAM 角色
  1. 登入 IAM 主控台。

  2. 選擇角色

  3. 選擇 Create Role (建立角色)

  4. 選取可信任執行個體類型下,選取 AWS 服務

  5. Choose the service that will use this role (選擇將使用此角色的服務) 下,選擇 Lambda (Lambda)

  6. 選擇 Next: Permissions (下一步:許可)

  7. 選擇 Create Policy (建立政策)

    Create Policy (建立政策) 主控台將開啟新的時段。在該視窗中,執行下列作業:

    1. JSON 標籤中,用以下政策取代現有政策。

      { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "lambda:InvokeFunction", "Resource": "*" } ] }
    2. 選擇 Review policy (檢閱政策)

    3. Review Policy (檢閱政策) 下,執行下列操作:

      1. Name (名稱) 中輸入名稱,例如 lambda_execute

      2. 選擇 Create Policy (建立政策)

  8. 在原本的 Create Role (建立角色) 主控台視窗中,執行下列動作:

    1. Attach permissions policies (連接許可政策) 下方,從下拉式清單中選擇您的 lambda_execute 政策。

      如果您在清單中沒有看到您的政策,請選擇清單頂端的重新整理按鈕。(請不要重新整理瀏覽器頁面!)

    2. 選擇 Next: Add Tags (下一步:新增標籤)

    3. 選擇 Next:Review (下一步:檢閱)

    4. Role name (角色名稱) 中輸入名稱,例如 lambda_invoke_function_assume_apigw_role

    5. 選擇 Create Role (建立角色)。

  9. 從角色清單中選擇您的 lambda_invoke_function_assume_apigw_role

  10. 選擇 Trust Relationships (信任關係) 標籤。

  11. 選擇 Edit trust relationship (編輯信任關係)

  12. 用以下內容取代現有政策:

    { "Version": "2012-10-17", "Statement": [ { "Sid": "", "Effect": "Allow", "Principal": { "Service": [ "lambda.amazonaws.com", "apigateway.amazonaws.com" ] }, "Action": "sts:AssumeRole" } ] }
  13. 選擇 Update Trust Policy (更新信任政策)

  14. 請記住您剛建立角色的角色 ARN。以供稍後使用。

建立 Calc Lambda 函數

接下來,您會使用 Lambda 主控台建立 Lambda 函數。

  1. 在 Lambda 主控台中,請選擇 Create function (建立函數)

  2. 選擇 Author from Scratch (從頭開始撰寫)

  3. 針對名稱,輸入 Calc

  4. 針對執行期,請選擇最新支援的 Node.jsPython 執行期。

  5. 選擇 建立函式

  6. 在 Lambda 主控台中,複製下列 Lambda 函數,並將其貼入程式碼編輯器。

    Node.js
    export const handler = async function (event, context) { console.log("Received event:", JSON.stringify(event)); if ( event.a === undefined || event.b === undefined || event.op === undefined ) { return "400 Invalid Input"; } const res = {}; res.a = Number(event.a); res.b = Number(event.b); res.op = event.op; if (isNaN(event.a) || isNaN(event.b)) { return "400 Invalid Operand"; } switch (event.op) { case "+": case "add": res.c = res.a + res.b; break; case "-": case "sub": res.c = res.a - res.b; break; case "*": case "mul": res.c = res.a * res.b; break; case "/": case "div": if (res.b == 0) { return "400 Divide by Zero"; } else { res.c = res.a / res.b; } break; default: return "400 Invalid Operator"; } return res; };
    Python
    import json def lambda_handler(event, context): print(event) try: (event['a']) and (event['b']) and (event['op']) except KeyError: return '400 Invalid Input' try: res = { "a": float( event['a']), "b": float( event['b']), "op": event['op']} except ValueError: return '400 Invalid Operand' if event['op'] == '+': res['c'] = res['a'] + res['b'] elif event['op'] == '-': res['c'] = res['a'] - res['b'] elif event['op'] == '*': res['c'] = res['a'] * res['b'] elif event['op'] == '/': if res['b'] == 0: return '400 Divide by Zero' else: res['c'] = res['a'] / res['b'] else: return '400 Invalid Operator' return res
  7. 在執行角色下,選擇選擇現有的角色

  8. 為您先前建立的 lambda_invoke_function_assume_apigw_role 角色輸入角色 ARN。

  9. 選擇 Deploy (部署)

此函數需要 a 輸入參數有兩個運算元 (bop) 和一個運算子 (event)。輸入是下列格式的 JSON 物件:

{ "a": "Number" | "String", "b": "Number" | "String", "op": "String" }

此函數會傳回計算的結果 (c) 和輸入。對於無效的輸入,該函數會傳回 null 值或「無效 op」字串做為結果。輸出具有下列 JSON 格式:

{ "a": "Number", "b": "Number", "op": "String", "c": "Number" | "String" }

您應該先在 Lambda 主控台中測試函數,再於後續步驟中將它與 API 整合。

測試 Calc Lambda 函式

以下是在 Lambda 主控台測試 Calc 函數的方式:

  1. 選擇測試標籤。

  2. 針對測試事件名稱,輸入 calc2plus5

  3. 將測試事件定義取代為下列內容:

    { "a": "2", "b": "5", "op": "+" }
  4. 選擇 Save (儲存)。

  5. 選擇 Test (測試)

  6. 展開 Execution result: succeeded (執行結果:成功)。請查看下列事項:

    { "a": 2, "b": 5, "op": "+", "c": 7 }

建立 Calc API

下列程序說明如何為您剛建立的 Calc Lambda 函數建立 API。在後續幾節中,您會將資源和方法新增至其中。

若要建立 API
  1. 在以下網址登入 API Gateway 主控台:https://console.aws.amazon.com/apigateway

  2. 如果這是您第一次使用 API Gateway,您會看到服務功能的介紹頁面。在 REST API 下方,選擇 Build (組建)。當 Create Example API (建立範例 API) 快顯出現時,選擇 OK (確定)

    如果這不是第一次使用 API Gateway,請選擇 Create API (建立 API)。在 REST API 下方,選擇組建

  3. 對於API 名稱,輸入 LambdaCalc

  4. 描述,請輸入描述。

  5. API 端點類型保持設定為區域

  6. 選擇建立 API

整合 1:建立 GET 方法與查詢參數搭配來呼叫 Lambda 函數

透過建立 GET 方法,將查詢字串參數傳遞至 Lambda 函數,您可以啟用 API,讓其可透過瀏覽器叫用。這種方法很有用,尤其適用於允許開放存取的 API。

在建立 API 之後,請建立資源。一般而言,會根據應用程式邏輯將 API 資源組織為資源樹狀結構。在此步驟中,您會建立 /calc 資源。

建立 /calc 資源
  1. 選擇建立資源

  2. 代理資源保持關閉。

  3. 資源路徑保持為 /

  4. 針對資源名稱,輸入 calc

  5. CORS (跨來源資源分享) 保持關閉。

  6. 選擇建立資源

透過建立 GET 方法,將查詢字串參數傳遞至 Lambda 函數,您可以啟用 API,讓其可透過瀏覽器叫用。這種方法很有用,尤其適用於允許開放存取的 API。

在此方法中,Lambda 需要使用 POST 請求來叫用任何 Lambda 函數。此範例示範前端方法請求中的 HTTP 方法可以與後端中的整合請求不同。

建立 GET 方法
  1. 選取 /calc 資源,然後選擇建立方法

  2. 針對方法類型,選取 GET

  3. 針對整合類型,選取 AWS 服務

  4. 在中 AWS 區域,選取 AWS 區域 您建立 Lambda 函數的位置。

  5. 針對 AWS 服務,選取 Lambda

  6. AWS 子網域保持空白。

  7. 針對 HTTP 方法,選取 POST

  8. 針對動作類型,選取使用路徑覆寫。這個選項可讓我們指定 Invoke 動作的 ARN,來執行 Calc 函數。

  9. 針對路徑覆寫,輸入 2015-03-31/functions/arn:aws:lambda:us-east-2:account-id:function:Calc/invocations。對於 account-id,輸入您的 AWS 帳戶 ID。在中us-east-2,輸入 AWS 區域 您建立 Lambda 函數的位置。

  10. 針對執行角色,輸入 lambda_invoke_function_assume_apigw_role 的角色 ARN。

  11. 請勿變更憑證快取預設逾時的設定。

  12. 選擇 [方法要求設定]

  13. 對於請求驗證程式,選取驗證查詢字串參數與標頭

    如果用戶端未指定所需參數,則此設定會造成系統傳回錯誤訊息。

  14. 選擇 URL 查詢字串參數

    現在,您可以在 /calc 資源上為 GET 方法設定查詢字串參數,以便它可以代表後端 Lambda 函數接收輸入。

    若要建立查詢字串參數,請執行下列動作:

    1. 選擇新增查詢字串

    2. 針對名稱,輸入 operand1

    3. 開啟必要

    4. 快取保持關閉。

    重複相同的步驟,並建立名為 operand2 的查詢字串和名為 operator 的查詢字串。

  15. 選擇建立方法

現在,請建立對應範本,以將用戶端提供的查詢字串翻譯為 Calc 函數所需的整合請求承載。此範本會將方法請求中所宣告的三個查詢字串參數對應至 JSON 物件的指定屬性值,作為後端 Lambda 函數的輸入。轉換過的 JSON 物件將會包含為整合請求承載。

將輸入參數對應至整合請求
  1. 整合請求索引標籤上,於整合請求設定下,選擇編輯

  2. 針對請求內文傳遞,選取未定義範本時 (建議)

  3. 選擇對應範本

  4. 選擇新增對應範本

  5. 針對內容類型,輸入 application/json

  6. 針對範本內文,輸入下列程式碼:

    { "a": "$input.params('operand1')", "b": "$input.params('operand2')", "op": "$input.params('operator')" }
  7. 選擇儲存

您現在可以測試您的 GET 方法,確認它已正確設定,可以叫用 Lambda 函數。

測試 GET 方法
  1. 選擇測試標籤。您可能需要選擇向右箭頭按鈕才能顯示此索引標籤。

  2. 針對查詢字串,輸入 operand1=2&operand2=3&operator=+

  3. 選擇測試

    結果看起來會與下列類似:

    在 API Gateway 中建立 API 作為 Lambda 代理

整合 2:建立 POST 方法與 JSON 承載搭配來呼叫 Lambda 函數

透過建立 POST 方法與 JSON 承載搭配來呼叫 Lambda 函數,讓用戶端必須在請求內文中提供後端函數的必要輸入。為了確保用戶端上傳正確的輸入資料,您將在承載上啟用請求驗證。

建立具有 JSON 承載的 POST 方法
  1. 選取 /calc 資源,然後選擇建立方法

  2. 針對方法類型,選取 POST

  3. 針對整合類型,選取 AWS 服務

  4. 在中 AWS 區域,選取 AWS 區域 您建立 Lambda 函數的位置。

  5. 針對 AWS 服務,選取 Lambda

  6. AWS 子網域保持空白。

  7. 針對 HTTP 方法,選取 POST

  8. 針對動作類型,選取使用路徑覆寫。這個選項可讓我們指定 Invoke 動作的 ARN,來執行 Calc 函數。

  9. 針對路徑覆寫,輸入 2015-03-31/functions/arn:aws:lambda:us-east-2:account-id:function:Calc/invocations。對於 account-id,輸入您的 AWS 帳戶 ID。在中us-east-2,輸入 AWS 區域 您建立 Lambda 函數的位置。

  10. 針對執行角色,輸入 lambda_invoke_function_assume_apigw_role 的角色 ARN。

  11. 請勿變更憑證快取預設逾時的設定。

  12. 選擇建立方法

現在,請建立輸入模型來說明輸入資料結構,並驗證傳入請求內文。

建立輸入模型
  1. 在主導覽窗格中,選擇模型

  2. 選擇建立模型

  3. 針對名稱,輸入 input

  4. 針對內容類型,輸入 application/json

    如果找不到相符的內容類型,則不會執行請求驗證。若要使用相同的模型,而不論內容類型為何,請輸入 $default

  5. 針對模型結構描述,輸入下列模型:

    { "type":"object", "properties":{ "a":{"type":"number"}, "b":{"type":"number"}, "op":{"type":"string"} }, "title":"input" }
  6. 選擇建立模型

您現在要建立輸出模型。此模型說明來自後端之計算輸出的資料結構。它可以用來將整合回應資料對應至不同模型。本教學依賴傳遞行為,而且不會使用此模型。

建立輸出模型
  1. 選擇建立模型

  2. 針對名稱,輸入 output

  3. 針對內容類型,輸入 application/json

    如果找不到相符的內容類型,則不會執行請求驗證。若要使用相同的模型,而不論內容類型為何,請輸入 $default

  4. 針對模型結構描述,輸入下列模型:

    { "type":"object", "properties":{ "c":{"type":"number"} }, "title":"output" }
  5. 選擇建立模型

您現在會建立結果模型。此模型說明所傳回回應資料的資料結構。其會參考 API 中所定義的輸入輸出結構描述。

建立結果模型
  1. 選擇建立模型

  2. 針對名稱,輸入 result

  3. 針對內容類型,輸入 application/json

    如果找不到相符的內容類型,則不會執行請求驗證。若要使用相同的模型,而不論內容類型為何,請輸入 $default

  4. 針對模型結構描述,使用您的 restapi-id 輸入以下模型。您的 restapi-id 會以括號列在以下流程中的主控台頂端:API Gateway > APIs > LambdaCalc (abc123).

    { "type":"object", "properties":{ "input":{ "$ref":"https://apigateway.amazonaws.com/restapis/restapi-id/models/input" }, "output":{ "$ref":"https://apigateway.amazonaws.com/restapis/restapi-id/models/output" } }, "title":"result" }
  5. 選擇建立模型

您現在要設定 POST 方法的方法請求,以在傳入請求內文上啟用請求驗證。

若要啟用 POST 方法的要求驗證
  1. 在主導覽窗格中,選擇資源,然後從資源樹狀目錄中選取 POST 方法。

  2. 方法請求索引標籤的方法請求設定下,選擇編輯

  3. 對於請求驗證程式,選取驗證內文

  4. 選擇請求內文,然後選擇新增模型

  5. 針對內容類型,輸入 application/json

    如果找不到相符的內容類型,則不會執行請求驗證。若要使用相同的模型,而不論內容類型為何,請輸入 $default

  6. 針對模型,選取輸入

  7. 選擇儲存

您現在可以測試您的 POST 方法,確認它已正確設定,可以叫用 Lambda 函數。

測試 POST 方法
  1. 選擇測試標籤。您可能需要選擇向右箭頭按鈕才能顯示此索引標籤。

  2. 針對請求內文,輸入下列 JSON 承載。

    { "a": 1, "b": 2, "op": "+" }
  3. 選擇 測試

    您應該會看到下列輸出:

    { "a": 1, "b": 2, "op": "+", "c": 3 }

整合 3:建立 GET 方法與路徑參數搭配來呼叫 Lambda 函數

現在,您將在透過一系列路徑參數所指定的資源上建立 GET 方法,來呼叫後端 Lambda 函數。路徑參數值指定 Lambda 函數的輸入資料。您需要使用映射範本將傳入路徑參數值對應至所需的整合請求承載。

產生的 API 資源結構看起來像這樣:

在 API Gateway 中建立 API 作為 Lambda 代理
建立 /{operand1}/{operand2}/{operator} 資源
  1. 選擇建立資源

  2. 針對資源路徑,選取 /calc

  3. 針對資源名稱,輸入 {operand1}

  4. CORS (跨來源資源分享) 保持關閉。

  5. 選擇建立資源

  6. 針對資源路徑,選取 /calc/{operand1}/

  7. 針對資源名稱,輸入 {operand2}

  8. CORS (跨來源資源分享) 保持關閉。

  9. 選擇建立資源

  10. 針對資源路徑,選取 /calc/{operand1}/{operand2}/

  11. 針對資源名稱,輸入 {operator}

  12. CORS (跨來源資源分享) 保持關閉。

  13. 選擇建立資源

此時,您要在 API Gateway 主控台中使用內建的 Lambda 整合來設定方法整合。

設定方法整合
  1. 選取 /{operand1}/{operand2}/{operator} 資源,然後選擇建立方法

  2. 針對方法類型,選取 GET

  3. 針對整合類型,選取 Lambda

  4. Lambda 代理整合保持關閉。

  5. 對於 Lambda 函數,請選取 AWS 區域 您建立 Lambda 函數的位置,然後輸入Calc

  6. 預設逾時保持開啟。

  7. 選擇建立方法

您現在要建立對應範本,以將建立 /calc/{operand1}/{operand2}/{operator} 資源時所宣告的三個 URL 路徑參數對應至 JSON 物件中的指定屬性值。因為 URL 路徑必須是 URL 編碼,所以必須將 division 運算子指定為 %2F,而非 /。此範本會先將 %2F 翻譯為 '/',再將它傳遞給 Lambda 函數。

建立對應範本
  1. 整合請求索引標籤上,於整合請求設定下,選擇編輯

  2. 針對請求內文傳遞,選取未定義範本時 (建議)

  3. 選擇對應範本

  4. 針對內容類型,輸入 application/json

  5. 針對範本內文,輸入下列程式碼:

    { "a": "$input.params('operand1')", "b": "$input.params('operand2')", "op": #if($input.params('operator')=='%2F')"/"#{else}"$input.params('operator')"#end }
  6. 選擇儲存

您現在可以測試您的 GET 方法,確認其已正確設定,可以叫用 Lambda 函數,並透過整合回應傳遞原始輸出,而不需要對應。

測試 GET 方法
  1. 選擇測試標籤。您可能需要選擇向右箭頭按鈕才能顯示此索引標籤。

  2. 對於路徑,執行下列動作:

    1. 對於 operand1,輸入 1

    2. 對於 operand2,輸入 1

    3. 對於運算子,輸入 +

  3. 選擇 Test (測試)

  4. 結果應如下所示:

    在 API Gateway 主控台中測試 GET 方法。

接著,您將模型化 result 結構描述後面之方法回應承載的資料結構。

在預設情況下,方法回應內文會獲指派空白模型。這會造成傳遞整合回應內文,而不進行對應。不過,當您為一個強型別語言 (例如 Java 或 Objective-C) 產生開發套件時,開發套件使用者將會收到一個空白物件做為結果。為了確保 REST 用戶端和開發套件用戶端都收到所需的結果,您必須使用預先定義的結構描述來模型化回應資料。在這裡,您將定義方法回應內文的模型,以及如何建構對應範本,將整合回應內文翻譯為方法回應內文。

建立方法回應
  1. 方法回應索引標籤上的回應 200 下,選擇編輯

  2. 請求內文下,選擇新增模型

  3. 針對內容類型,輸入 application/json

  4. 針對模型,選取結果

  5. 選擇儲存

設定方法回應內文的模型,可確保將回應資料轉換為特定開發套件的 result 物件。為了確保據此映射整合回應資料,您將需要映射範本。

建立對應範本
  1. 整合回應索引標籤上,於預設 - 回應下,選擇編輯

  2. 選擇對應範本

  3. 針對內容類型,輸入 application/json

  4. 針對範本內文,輸入下列程式碼:

    #set($inputRoot = $input.path('$')) { "input" : { "a" : $inputRoot.a, "b" : $inputRoot.b, "op" : "$inputRoot.op" }, "output" : { "c" : $inputRoot.c } }
  5. 選擇儲存

測試對應範本
  1. 選擇測試標籤。您可能需要選擇向右箭頭按鈕才能顯示此索引標籤。

  2. 對於路徑,執行下列動作:

    1. 對於 operand1,輸入 1

    2. 對於 operand2,輸入 2

    3. 對於運算子,輸入 +

  3. 選擇 測試

  4. 結果如下所示:

    { "input": { "a": 1, "b": 2, "op": "+" }, "output": { "c": 3 } }

此時只能透過 API Gateway 主控台中的測試功能來呼叫 API。若要讓 API 可供用戶端使用,您需要部署 API。每當新增、修改或刪除資源或方法、更新資料映射,或更新階段設定時,請一律務必重新部署您的 API。否則,您 API 的用戶端將無法使用新功能或更新,如下所示:

部署 API
  1. 選擇部署 API

  2. 針對階段,選取新階段

  3. 針對階段名稱,輸入 Prod

  4. 描述,請輸入描述。

  5. 選擇部署

  6. (選用) 針對階段詳細資訊下的調用 URL,您可以選擇複製圖示以複製 API 的調用 URL。您可以使用此項與 PostmancURL 這類工具搭配,來測試您的 API。

注意

每當新增、修改或刪除資源或方法、更新資料映射,或更新階段設定時,請一律重新部署您的 API。否則,您 API 的用戶端將無法使用新功能或更新。