

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

# 教學：建立具 Lambda 代理整合的 REST API
<a name="api-gateway-create-api-as-simple-proxy-for-lambda"></a>

[Lambda 代理整合](set-up-lambda-proxy-integrations.md)是一種輕量型彈性 API Gateway API 整合類型，可讓您整合 API 方法 (或整個 API) 與 Lambda 函數。Lambda 函數的編寫方式可以是 [Lambda 支援的任何語言](https://docs.aws.amazon.com/lambda/latest/dg/lambda-runtimes.html)。因為它是代理整合，所以您可以隨時變更 Lambda 函數實作，無需重新部署您的 API。

在此教學中，您將執行下列操作：
+ 建立 "Hello, World\$1" Lambda 函數作為 API 的後端。
+ 建立和測試 具有 Lambda 代理整合的 API。

**Topics**
+ [建立 "Hello, World\$1" Lambda 函式](#api-gateway-proxy-integration-create-lambda-backend)
+ [建立 "Hello, World\$1" API](#api-gateway-create-api-as-simple-proxy-for-lambda-build)
+ [部署和測試 API](#api-gateway-create-api-as-simple-proxy-for-lambda-test)

## 建立 "Hello, World\$1" Lambda 函式
<a name="api-gateway-proxy-integration-create-lambda-backend"></a>

**建立 "Hello, World\$1" Lambda 控制台中的 Lambda 函數**

1. 在以下網址登入 Lambda 主控台：[https://console.aws.amazon.com/lambda](https://console.aws.amazon.com/lambda)。

1. 在 AWS 導覽列上，選擇 [AWS 區域](https://docs.aws.amazon.com/general/latest/gr/apigateway.html)。
**注意**  
記下您建立 Lambda 函數的區域。在建立 API 時，您將需要此區域。

1. 在導覽窗格中，選擇 **Functions (函數)**。

1. 選擇 **Create function (建立函數)**。

1. 選擇 **Author from scratch** (從頭開始撰寫)。

1. 在 **Basic information (基本資訊)** 下，請執行下列動作：

   1. 在**函數名稱** 中，輸入 **GetStartedLambdaProxyIntegration**。

   1. 針對**執行期**，請選擇最新支援的 **Node.js** 或 **Python** 執行期。

   1. 對於**架構**，請保留預設設定。

   1. 在**許可**下，展開**變更預設執行角色**。從**執行角色**下拉式清單中，選擇**從 AWS 政策範本建立新角色**。

   1. 在**角色名稱** 中，輸入 **GetStartedLambdaBasicExecutionRole**。

   1. 將 **Policy templates (政策範本)** 欄位留白。

   1. 選擇 **Create function (建立函數)**。

1. 在內嵌程式碼編輯器的 **Function code (函數程式碼)** 下，複製/貼上下列程式碼：

------
#### [ Node.js ]

   ```
   export const handler = async(event, context) => {
       console.log('Received event:', JSON.stringify(event, null, 2));
       var res ={
           "statusCode": 200,
           "headers": {
               "Content-Type": "*/*"
           }
       };
       var greeter = 'World';
       if (event.greeter && event.greeter!=="") {
           greeter =  event.greeter;
       } else if (event.body && event.body !== "") {
           var body = JSON.parse(event.body);
           if (body.greeter && body.greeter !== "") {
               greeter = body.greeter;
           }
       } else if (event.queryStringParameters && event.queryStringParameters.greeter && event.queryStringParameters.greeter !== "") {
           greeter = event.queryStringParameters.greeter;
       } else if (event.multiValueHeaders && event.multiValueHeaders.greeter && event.multiValueHeaders.greeter != "") {
           greeter = event.multiValueHeaders.greeter.join(" and ");
       } else if (event.headers && event.headers.greeter && event.headers.greeter != "") {
           greeter = event.headers.greeter;
       } 
       res.body = "Hello, " + greeter + "!";
       return res
   };
   ```

------
#### [ Python ]

   ```
   import json
   
   
   def lambda_handler(event, context):
       print(event)
   
       greeter = 'World'
   
       try:
           if (event['queryStringParameters']) and (event['queryStringParameters']['greeter']) and (
                   event['queryStringParameters']['greeter'] is not None):
               greeter = event['queryStringParameters']['greeter']
       except KeyError:
           print('No greeter')
   
       try:
           if (event['multiValueHeaders']) and (event['multiValueHeaders']['greeter']) and (
                   event['multiValueHeaders']['greeter'] is not None):
               greeter = " and ".join(event['multiValueHeaders']['greeter'])
       except KeyError:
           print('No greeter')
   
       try:
           if (event['headers']) and (event['headers']['greeter']) and (
                   event['headers']['greeter'] is not None):
               greeter = event['headers']['greeter']
       except KeyError:
           print('No greeter')
   
       if (event['body']) and (event['body'] is not None):
           body = json.loads(event['body'])
           try:
               if (body['greeter']) and (body['greeter'] is not None):
                   greeter = body['greeter']
           except KeyError:
               print('No greeter')
   
       res = {
           "statusCode": 200,
           "headers": {
               "Content-Type": "*/*"
           },
           "body": "Hello, " + greeter + "!"
       }
   
       return res
   ```

------

1. 選擇 **Deploy (部署)**。

## 建立 "Hello, World\$1" API
<a name="api-gateway-create-api-as-simple-proxy-for-lambda-build"></a>

立即為您的 "Hello, World\$1" 建立 API 使用 API Gateway 主控台的 Lambda 函數。

**建立 "Hello, World\$1" API**

1. 在以下網址登入 API Gateway 主控台：[https://console.aws.amazon.com/apigateway](https://console.aws.amazon.com/apigateway)。

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

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

1.  對於**API 名稱**，輸入 **LambdaProxyAPI**。

1. 在**描述**，請輸入描述。

1. 將 **API 端點類型**保持設定為**區域**。

1. 針對 **IP 位址類型**，選擇 **IPv4**。

1. 選擇**建立 API**。

在建立 API 之後，請建立資源。一般而言，會根據應用程式邏輯將 API 資源組織為資源樹狀結構。在此範例中，您會建立 **/helloworld** 資源。

**建立資源**

1. 選擇**建立資源**。

1. 讓**代理資源**保持關閉。

1. 將**資源路徑**保持為 `/`。

1. 針對**資源名稱**，輸入 **helloworld**。

1. 讓 **CORS (跨來源資源分享)** 保持關閉。

1. 選擇**建立資源**。

 在代理整合中，透過一個代表任何 HTTP 方法的囊括型 `ANY` 方法，將整個請求按現狀傳送到後端 Lambda 函數。實際的 HTTP 方法由用戶端在執行時間指定。`ANY` 方法可讓使用針對所有支援的 HTTP 方法而設定的單一 API 方法：`DELETE`、`GET`、`HEAD`、`OPTIONS`、`PATCH`、`POST` 和 `PUT`。

**建立 `ANY` 方法**

1. 選取 **/helloworld** 資源，然後選擇**建立方法**。

1. 針對**方法類型**，選取 **ANY**。

1. 針對**整合類型**，選取 **Lambda 函數**。

1. 開啟 **Lambda 代理整合**。

1. 針對 **Lambda 函數**，選取您建立 Lambda 函數 AWS 區域 的 ，然後輸入函數名稱。

1. 若要使用 29 秒的預設逾時值，請將**預設逾時**保持開啟。若要設定自訂逾時，請選擇**預設逾時**，然後輸入介於 `50` 和 `29000` 毫秒之間的逾時值。

1. 選擇**建立方法**。

## 部署和測試 API
<a name="api-gateway-create-api-as-simple-proxy-for-lambda-test"></a>

**部署 API**

1. 選擇**部署 API**。

1. 針對**階段**，選取**新階段**。

1. 針對**階段名稱**，輸入 **test**。

1. 在**描述**，請輸入描述。

1. 選擇**部署**。

1. 在**階段詳細資訊**下，選擇複製圖示以複製 API 的調用 URL。

### 使用瀏覽器和 cURL 來測試具有 Lambda 代理整合的 API
<a name="api-gateway-create-api-as-simple-proxy-for-lambda-test-curl"></a>

您可以使用瀏覽器或 [cURL](https://curl.se/) 來測試您的 API。

若要僅使用查詢字串參數來測試 `GET` 請求，您可以將 API `helloworld` 資源的 URL 輸入至瀏覽器位址列。

若要建立適用於 API `helloworld` 資源的 URL，請將資源 `helloworld` 和查詢字串參數 `?greeter=John` 附加至您的調用 URL。您的 URL 看起來應該如下所示。

```
https://r275xc9bmd.execute-api.us-east-1.amazonaws.com/test/helloworld?greeter=John
```

針對其他方法，您必須使用更進階的 REST API 測試公用程式，例如 [POSTMAN](https://www.postman.com/) 或 [cURL](https://curl.se/)。本教學使用 cURL。以下 cURL 命令範例假設 cURL 已安裝在您的電腦上。

**若要使用 cURL 測試已部署的 API：**

1. 開啟終端機視窗。

1. 複製以下 cURL 命令並將它貼到終端視窗，然後將調用 URL 取代為您在上一個步驟中複製的 URL，再將 **/helloworld** 新增至該 URL 的結尾。
**注意**  
如果您是在 Windows 上執行命令，請改用此語法：  

   ```
   curl -v -X POST "https://r275xc9bmd.execute-api.us-east-1.amazonaws.com/test/helloworld" -H "content-type: application/json" -d "{ \"greeter\": \"John\" }"
   ```

   1. 使用查詢字串參數 `?greeter=John` 呼叫 API：

      ```
      curl -X GET 'https://r275xc9bmd.execute-api.us-east-1.amazonaws.com/test/helloworld?greeter=John'
      ```

   1. 使用標頭參數 `greeter:John` 呼叫 API：

      ```
      curl -X GET https://r275xc9bmd.execute-api.us-east-1.amazonaws.com/test/helloworld \
        -H 'content-type: application/json' \
        -H 'greeter: John'
      ```

   1. 使用內文 `{"greeter":"John"}` 呼叫 API：

      ```
      curl -X POST https://r275xc9bmd.execute-api.us-east-1.amazonaws.com/test/helloworld \
        -H 'content-type: application/json' \
        -d '{ "greeter": "John" }'
      ```

   在所有情況下，輸出都是具有下列回應內文的 200 回應：

   ```
   Hello, John!
   ```