練習 - 將邏輯新增至函數應用程式

已完成

讓我們繼續進行齒輪驅動範例,並新增溫度服務的邏輯。 具體而言,我們將從 HTTP 要求接收資料。

函式需求

首先,我們需要為邏輯定義一些需求:

  • 從 0 到 25 度的溫度應該標示為正常
  • 從 25 到 50 度的溫度應該標示為警告
  • 超過 50 度的溫度應該標示為危險

將函式新增至函數應用程式

如上一個單元中所討論,Azure 會提供可協助您建置函式的範本。 在此單元中,您將使用 HttpTrigger 範本來實作溫度服務。

  1. 在上一個練習中,您已部署函式應用程式並加以開啟。 如果尚未開啟,您可以從首頁選取 [所有資源],然後選取您的函式應用程式,其具有如 escalator-functions-xxx 的名稱。

  2. [函數] 索引標籤底下的 [函數應用程式] 畫面上,選取 [在 Azure 入口網站中建立]。 [建立函式] 窗格隨即出現。

  3. 在 [選取範本] 底下,選取 [HTTP 觸發程序],然後選取 [下一頁]

  1. 讓 [函數名稱] 保留為「HttpTrigger1」,讓 [授權等級] 保留為 [函數],然後選取 [建立]。 函數 HttpTrigger1 隨即建立,並顯示在 [HttpTrigger1 函數] 窗格中。

  2. 選取 [編碼 + 測試] 索引標籤。程式碼編輯器隨即開啟,顯示函式的 index.js 程式碼檔案內容。 HTTP 範本所產生的預設程式碼隨即出現在下列程式碼片段中。

    module.exports = async function (context, req) {
        context.log('JavaScript HTTP trigger function processed a request.');
    
        const name = (req.query.name || (req.body && req.body.name));
        const responseMessage = name
            ? "Hello, " + name + ". This HTTP triggered function executed successfully."
            : "This HTTP triggered function executed successfully. Pass a name on the query string or in the request body for a personalized response.";
    
        context.res = {
            // status: 200, /* Defaults to 200 */
            body: responseMessage
        };
    }
    

    您的函式預期會透過 HTTP 要求查詢字串傳遞名稱,或作為要求主體的一部分來傳遞。 函式的回應是傳回訊息「<name>,您好。此 HTTP 觸發程序函數已成功執行。」,以回應要求所傳送的名稱

    從 [來源檔案] 下拉式清單中,選取 function.json 來檢視函式的設定,其看起來應該會像下列程式碼。

    {
      "bindings": [
        {
          "authLevel": "function",
          "type": "httpTrigger",
          "direction": "in",
          "name": "req",
          "methods": [
            "get",
            "post"
          ]
        },
        {
          "type": "http",
          "direction": "out",
          "name": "res"
        }
      ]
    }
    

    此設定檔宣告函數會在收到 HTTP 要求時執行。 輸出繫結宣告回應會以 HTTP 回應的形式傳送。

  1. 在 [範本詳細資料] 區段的 [新增函式] 欄位中,輸入 DriveGearTemperatureService。 將 [授權等級] 保留為函式,然後選取 [建立] 來建立函式。 DriveGearTemperatureService 函式的 [概觀] 窗格隨即出現。

  2. 在 [函式] 功能表中,選取 [程式碼 + 測試]。 程式碼編輯器會開啟並顯示 run.ps1 程式碼檔案的內容。 下列程式碼片段會列出範本為我們產生的預設程式碼。

    using namespace System.Net
    
    # Input bindings are passed in via param block.
    param($Request, $TriggerMetadata)
    
    # Write to the Azure Functions log stream.
    Write-Host "PowerShell HTTP trigger function processed a request."
    
    # Interact with query parameters or the body of the request.
    $name = $Request.Query.Name
    if (-not $name) {
        $name = $Request.Body.Name
    }
    
    $body = "This HTTP triggered function executed successfully. Pass a name in the query string or in the request body for a personalized response."
    
    if ($name) {
        $body = "Hello, $name. This HTTP triggered function executed successfully."
    }
    
    # Associate values to output bindings by calling 'Push-OutputBinding'.
    Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{
        StatusCode = [HttpStatusCode]::OK
        Body = $body
    })
    

    我們的函式預期會透過 HTTP 要求查詢字串傳遞名稱,或作為要求主體的一部分來傳遞。 HTTP 函式必須透過寫入其輸出繫結來產生回應,這是使用 Push-OutputBinding Cmdlet 在 PowerShell 函式中完成的。 此函式會傳回訊息「$name,您好」,以回應在要求中傳送的名稱。

  3. 從來源下拉式清單中,選取 [function.json] 來檢視函式的設定,畫面應該如下所示。

    {
      "bindings": [
        {
          "authLevel": "function",
          "type": "httpTrigger",
          "direction": "in",
          "name": "Request",
          "methods": [
            "get",
            "post"
          ]
        },
        {
          "type": "http",
          "direction": "out",
          "name": "Response"
        }
      ]
    }
    

    此設定會宣告當它收到 HTTP 要求時,函式已執行。 輸出繫結宣告回應會以 HTTP 回應的形式傳送。

測試函式

提示

cURL 是一種命令列工具,可用來傳送或接收檔案。 cURL 隨附於 Linux、macOS 和 Windows 10,絕大多數其他作業系統都可以下載。 cURL 支援多種通訊協定,如 HTTP、HTTPS、FTP、FTPS、SFTP、LDAP、TELNET、SMTP、POP3 等等。 如需詳細資訊,請前往下面連結:

若要測試函數,您可以在命令列上使用 cURL,將 HTTP 要求傳送至函數 URL。

  1. 展開 [觸發程序函式] 窗格底部的 [記錄] 框架。 在 [記錄] 框架頂端的下拉式清單中選取 [Filesystem Logs] (檔案系統記錄檔)。 記錄框架應每分鐘開始累積追蹤通知。

  2. 若要尋找函式的端點 URL,請從命令列選取 [取得函式 URL],如下圖所示。 選取 URL 結尾處的 [複製到剪貼簿] 圖示,以儲存此連結。 將此連結儲存至記事本或類似的應用程式,以供稍後使用。

    Azure 入口網站的螢幕擷取畫面,其中顯示函式編輯器,且 [取得函式 URL] 按鈕已醒目提示。

  3. 開啟命令提示字元,然後執行 cURL 將 HTTP 要求傳送至函式 URL。 請務必使用您在先前步驟中複製的 URL。

    curl "<your-https-url>"
    

    提示

    您可能需要將 URL 包覆在引號中,以避免 URL 中出現特殊字元的問題。
    如果您使用 Windows,請從命令提示字元執行 cURL。 PowerShell 有一個 curl 命令,但其為 Invoke-WebRequest 的別名,與 cURL 不同。

    回應應該會顯示如下。

    This HTTP triggered function executed successfully. Pass a name on the query string or in the request body for a personalized response.
    

    現在,請在要求中傳入名稱。 為此,您必須將名為 name 的查詢字串參數新增至 URL。 下列範例會新增查詢字串參數 name=Azure

    curl "<your-https-url>&name=Azure"
    

    回應應該會顯示如下。

    Hello, Azure. This HTTP triggered function executed successfully.
    

    函式已成功執行,並傳回您在要求中傳入的名稱。

保護 HTTP 觸發程序

HTTP 觸發程序可讓您使用 API 金鑰封鎖未知的呼叫端,但需要金鑰作為要求的一部分。 當您建立函式時,您要選取 [授權層級]。 依預設,等級會設定為 [函數],因而需要函數專用的 API 金鑰。 此外也可設定為「管理員」以使用全域主要金鑰,或設為「匿名」以指出不需要金鑰。 您也可以在建立後透過函式的屬性變更授權層級。

因為您在建立此函式時指定了「函數」,所以,當您傳送 HTTP 要求時需要提供金鑰。 您可以將它傳送為名為 code 的查詢字串參數。 或者,使用慣用的方法,並將它當作名為 x-functions-key 的 HTTP 標頭傳遞。

  1. 若要尋找函數金鑰,請在 [概觀] 功能表上的 [函數] 索引標籤下選取函數的名稱 (例如「HttpTriger1」),以開啟 [編碼 + 測試] 功能表。 然後,選取 [函數金鑰] 索引標籤。

  2. 根據預設,函式金鑰值是隱藏的。 選取 [顯示值] 以顯示預設函數金鑰值。 將 [值] 欄位的內容複寫到剪貼簿,然後將此金鑰儲存在 [記事本] 或類似的應用程式以供稍後使用。

    顯示 [函式金鑰] 窗格的螢幕擷取畫面,並已醒目提示顯示的函式金鑰。

  3. 若要使用函式金鑰測試函式,請開啟命令提示字元並執行 cURL,以將 HTTP 要求傳送至函式 URL。 將 <your-function-key> 取代為您儲存的函數金鑰值,並將 <your-https-url> 取代為您函數的 URL。

    curl --header "Content-Type: application/json" --header "x-functions-key: <your-function-key>" --request POST --data "{\"name\": \"Azure Function\"}" <your-https-url>
    
  4. 檢閱 cURL 命令,並確認其具有下列值:

    • 已新增類型為 application/jsonContent-Type 標頭值。
    • 已將函式金鑰當成標頭值 x-functions-key 來傳遞。
    • 已使用 POST 要求。
    • 使用函式的 URL 傳遞 Azure 函式。
  5. 檢查記錄。

    [程式碼 + 測試] 窗格應該會開啟顯示記錄檔輸出的工作階段 (確定已在 [記錄] 窗格頂端的下拉式清單中選取 [Filesystem Logs] (檔案系統記錄檔))。 記錄檔會以您的要求狀態進行更新,應該會顯示如下:

```output
2022-02-16T22:34:10.473 [Information] Executing 'Functions.HttpTrigger1' (Reason='This function was programmatically called via the host APIs.', Id=4f503b35-b944-455e-ba02-5205f9e8b47a)
2022-02-16T22:34:10.539 [Information] JavaScript HTTP trigger function processed a request.
2022-02-16T22:34:10.562 [Information] Executed 'Functions.HttpTrigger1' (Succeeded, Id=4f503b35-b944-455e-ba02-5205f9e8b47a, Duration=114ms)
```
```output
2022-02-16T21:07:11.340 [Information] INFORMATION: PowerShell HTTP trigger function processed a request.
2022-02-16T21:07:11.449 [Information] Executed 'Functions.DriveGearTemperatureService' (Succeeded, Id=25e2edc3-542f-4629-a152-cf9ed99680d8, Duration=1164ms)
```

將商務邏輯新增至函數

讓我們將邏輯新增至函式,檢查所收到的溫度讀數,並設定每個溫度讀數的狀態。

我們的函式預期溫度讀數陣列。 下列 JSON 程式碼片段是我們會傳送至函數的要求本文範例。 JavaScript 或 PowerShell 的陣列名稱可能會略微不同,但陣列中的每個項目都有識別碼、時間戳記和溫度。

{
    "Readings": [
        {
            "driveGearId": 1,
            "timestamp": 1534263995,
            "temperature": 23
        },
        {
            "driveGearId": 3,
            "timestamp": 1534264048,
            "temperature": 45
        },
        {
            "driveGearId": 18,
            "timestamp": 1534264050,
            "temperature": 55
        }
    ]
}

讓我們以下列會實作商務邏輯的程式碼來取代函數中的預設程式碼。

HttpTrigger1 函式窗格中,開啟 index.js 檔案,並將其取代為下列程式碼。 在完成變更後,從命令列選取 [儲存],將更新儲存至檔案。

module.exports = function (context, req) {
    context.log('Drive Gear Temperature Service triggered');
    if (req.body && req.body.readings) {
        req.body.readings.forEach(function(reading) {

            if(reading.temperature<=25) {
                reading.status = 'OK';
            } else if (reading.temperature<=50) {
                reading.status = 'CAUTION';
            } else {
                reading.status = 'DANGER'
            }
            context.log('Reading is ' + reading.status);
        });

        context.res = {
            // status: 200, /* Defaults to 200 */
            body: {
                "readings": req.body.readings
            }
        };
    }
    else {
        context.res = {
            status: 400,
            body: "Please send an array of readings in the request body"
        };
    }
    context.done();
};

我們新增的邏輯很簡單。 我們會逐一查看陣列,並根據溫度欄位的值,將狀態設定為正常警告危險。 然後傳回已將狀態欄位新增至每個項目的讀數陣列。

當您展開窗格底部的 [記錄] 時,請注意 Log 陳述式。 當函式執行時,這些陳述式會在 [記錄] 視窗中新增訊息。

測試商務邏輯

我們將會使用 [開發人員]>[程式碼 + 測試] 中的 [測試/執行] 功能來測試函式。

  1. 在 [編碼 + 測試] 索引標籤上,選取 [測試/執行]。 在 [輸入] 索引標籤中,以下列程式碼取代 [本文] 文字輸入框的內容,以便建立我們的範例要求。

    {
        "readings": [
            {
                "driveGearId": 1,
                "timestamp": 1534263995,
                "temperature": 23
            },
            {
                "driveGearId": 3,
                "timestamp": 1534264048,
                "temperature": 45
            },
            {
                "driveGearId": 18,
                "timestamp": 1534264050,
                "temperature": 55
            }
        ]
    }
    

開啟 run.ps1 檔案,並以下列程式碼取代內容。 在完成變更後,從命令列選取 [儲存],將更新儲存至檔案。

using namespace System.Net

param($Request, $TriggerMetadata)

Write-Host "Drive Gear Temperature Service triggered"

$readings = $Request.Body.Readings
if ($readings) {
    foreach ($reading in $readings) {
        if ($reading.temperature -le 25) {
            $reading.Status = "OK"
        }
        elseif ($reading.temperature -le 50) {
            $reading.Status = "CAUTION"
        }
        else {
            $reading.Status = "DANGER"
        }

        Write-Host "Reading is $($reading.Status)"
    }

    $status = [HttpStatusCode]::OK
    $body = $readings
}
else {
    $status = [HttpStatusCode]::BadRequest
    $body = "Please send an array of readings in the request body"
}

Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{
    StatusCode = $status
    Body = $body
})

我們新增的邏輯很簡單。 我們會逐一查看陣列,並根據溫度欄位的值,將狀態設定為正常警告危險。 然後傳回已將狀態欄位新增至每個項目的讀數陣列。

請注意對 Write-Host Cmdlet 的呼叫。 當函式執行時,這些陳述式會在 [記錄] 視窗中新增訊息。

測試商務邏輯

我們將會使用 [開發人員]>[程式碼 + 測試] 中的 [測試/執行] 功能來測試函式。

  1. 在 [編碼 + 測試] 索引標籤上,選取 [測試/執行]。 在 [輸入] 索引標籤中,以下列程式碼取代 [本文] 文字輸入框的內容,以便建立我們的範例要求。

    {
        "Readings": [
            {
                "driveGearId": 1,
                "timestamp": 1534263995,
                "temperature": 23
            },
            {
                "driveGearId": 3,
                "timestamp": 1534264048,
                "temperature": 45
            },
            {
                "driveGearId": 18,
                "timestamp": 1534264050,
                "temperature": 55
            }
        ]
    }
    
  1. 選取執行。 [輸出] 索引標籤會顯示 HTTP 回應碼和內容。 若要查看記錄訊息,請在窗格底部的飛出視窗中開啟 [記錄] 索引標籤 (如果尚未開啟)。 下圖顯示在輸出窗格中的範例回應,以及 [記錄] 窗格中的訊息。

    Azure 函式編輯器的螢幕擷取畫面,其中顯示 [測試] 與 [記錄] 索引標籤。

    [輸出] 索引標籤中可看到每個讀數均已正確新增狀態欄位。

  2. 在左側的 [開發人員] 功能表中,選取 [監視] 即可看到要求已記錄至 Application Insights。 您函式的 [監視器] 窗格隨即出現。

    窗格的 [引動過程] 索引標籤會顯示每個函數引動過程的 [引動過程追蹤]。 選取其中一個引動過程的 [資料 (UTC)] 值,並檢視關於函數執行的詳細資料。