Ćwiczenie — Dodawanie logiki do aplikacji funkcji

Ukończone

Kontynuujmy pracę z przykładem dotyczącym mechanizmu napędowego i dodajmy logikę dla usługi temperatury. Ściślej mówiąc, będziemy odbierać dane z żądania HTTP.

Wymagania funkcji

Najpierw musimy zdefiniować kilka wymagań dotyczących naszej logiki:

  • Temperatury z zakresu od 0 do 25 stopni powinny być oznaczone jako OK.
  • Temperatury powyżej 25 do 50 stopni powinny być oznaczone jako OSTRZEŻENIE.
  • Temperatury powyżej 50 stopni powinny być oflagowane jako NIEBEZPIECZEŃSTWO.

Dodawanie funkcji do aplikacji funkcji

Jak opisano w poprzedniej lekcji, platforma Azure udostępnia szablony, które ułatwiają tworzenie funkcji. W tej lekcji użyjesz szablonu HttpTrigger do zaimplementowania usługi temperatury.

  1. W poprzednim ćwiczeniu wdrożono aplikację funkcji i otwarto ją. Jeśli nie jest jeszcze otwarty, możesz go otworzyć na stronie głównej, wybierając pozycję Wszystkie zasoby, a następnie wybierając aplikację funkcji o nazwie podobną do escalator-functions-xxx.

  2. Na ekranie Aplikacja funkcji na karcie Funkcje wybierz pozycję Utwórz w witrynie Azure Portal. Zostanie wyświetlone okienko Tworzenie funkcji .

  3. W obszarze Wybierz szablon wybierz pozycję Wyzwalacz HTTP.

  1. Wybierz pozycję Utwórz. Element HttpTrigger1 jest tworzony i wyświetlany w okienku Funkcji HttpTrigger1 .

  2. W menu Deweloper po lewej stronie wybierz pozycję Kod i testowanie. Zostanie otwarty edytor kodu wyświetlający zawartość pliku kodu index.js dla funkcji. Domyślny kod wygenerowany przez szablon HTTP pojawia się w poniższym fragmencie kodu.

    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
        };
    }
    

    Funkcja oczekuje przekazania nazwy za pośrednictwem ciągu zapytania żądania HTTP lub jako części treści żądania. Funkcja odpowiada, zwracając komunikat Hello, <name>. Ta funkcja wyzwalana przez protokół HTTP została wykonana pomyślnie. Zwraca ona nazwę wysłaną w żądaniu.

    Z listy rozwijanej plik źródłowy wybierz plik function.json , aby wyświetlić konfigurację funkcji, która powinna wyglądać podobnie do poniższego kodu.

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

    Ten plik konfiguracji deklaruje, że funkcja jest uruchamiana po odebraniu żądania HTTP. Powiązanie wyjściowe deklaruje, że odpowiedź jest wysyłana jako odpowiedź HTTP.

  1. W sekcji Szczegóły szablonu w polu Nowa funkcja wprowadź DriveGearTemperatureService. Pozostaw poziom autoryzacji jako Funkcja, a następnie wybierz pozycję Utwórz, aby utworzyć funkcję. Zostanie wyświetlone okienko Przegląd dla funkcji DriveGearTemperatureService .

  2. W menu Funkcja wybierz pozycję Kod i test. Edytor kodu zostanie otwarty z zawartością pliku kodu run.ps1 . Poniższy fragment kodu przedstawia domyślny kod wygenerowany dla nas przez szablon.

    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
    })
    

    Nasza funkcja oczekuje przekazania nazwy za pośrednictwem ciągu zapytania żądania HTTP lub w treści żądania. Funkcje HTTP muszą generować odpowiedź przez zapisywanie w ich powiązaniu danych wyjściowych, co jest wykonywane w funkcjach programu PowerShell przy użyciu polecenia cmdlet Push-OutputBinding. Ta funkcja zwraca komunikat Hello, $name, powtarzając nazwę, która została wysłana w żądaniu.

  3. Z listy rozwijanej źródło wybierz plik function.json , aby wyświetlić konfigurację funkcji, która powinna wyglądać podobnie do poniższej.

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

    Ta konfiguracja deklaruje, że funkcja jest uruchamiana po odebraniu żądania HTTP. Powiązanie wyjściowe deklaruje, że odpowiedź jest wysyłana jako odpowiedź HTTP.

Testowanie funkcji

Napiwek

cURL to narzędzie wiersza polecenia, które umożliwia wysyłanie i odbieranie plików. Wchodzi ono w skład systemu Linux, macOS i Windows 10. Można je pobrać dla większości systemów operacyjnych. Narzędzie cURL obsługuje wiele protokołów, na przykład HTTP, HTTPS, FTP, FTPS, SFTP, LDAP, TELNET, SMTP, POP3 itd. Aby uzyskać więcej informacji, skorzystaj z następujących linków:

Aby przetestować funkcję, możesz wysłać żądanie HTTP na adres URL funkcji, używając narzędzia cURL w wierszu polecenia.

  1. Rozwiń ramkę Dzienniki w dolnej części okienka funkcji wyzwalacza. Wybierz pozycję Dzienniki systemu plików z listy rozwijanej w górnej części ramki Dzienniki. Ramka dziennika powinna zaczynać naliczanie powiadomień śledzenia co minutę.

  2. Aby znaleźć adres URL punktu końcowego funkcji, na pasku poleceń wybierz pozycję Pobierz adres URL funkcji, jak pokazano na poniższej ilustracji. Skopiuj ten link, wybierając ikonę Kopiuj do schowka na końcu adresu URL. Zapisz ten link w Notatnik lub podobnej aplikacji do późniejszego użycia.

    Screenshot of the Azure portal showing the function editor, with the Get function URL button highlighted.

  3. Otwórz wiersz polecenia i uruchom polecenie cURL, aby wysłać żądanie HTTP do adresu URL funkcji. Pamiętaj, aby użyć adresu URL skopiowanego w poprzednim kroku.

    curl "<your-https-url>"
    

    Napiwek

    Może być konieczne zawinięcie adresu URL w cudzysłowie, aby uniknąć problemów ze znakami specjalnymi w adresie URL.
    Jeśli korzystasz z systemu Windows, uruchom polecenie cURL w wierszu polecenia. Program PowerShell ma polecenie curl , ale jest to alias invoke-WebRequest, który nie jest taki sam jak cURL.

    Odpowiedź powinna wyglądać następująco.

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

    Teraz przekaż nazwę w żądaniu. W tym celu należy dodać parametr ciągu zapytania o nazwie name do adresu URL. W poniższym przykładzie dodano parametr name=Azureciągu zapytania .

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

    Odpowiedź powinna wyglądać następująco.

    Hello, Azure. This HTTP triggered function executed successfully.
    

    Funkcja została wykonana pomyślnie i zwróciła nazwę przekazaną w żądaniu.

Zabezpieczanie wyzwalaczy HTTP

Wyzwalacze HTTP umożliwiają używanie kluczy interfejsu API do blokowania nieznanych wywołań przez wymaganie klucza w ramach żądania. Podczas tworzenia funkcji należy wybrać poziom autoryzacji. Domyślnie jest ustawiona wartość Funkcja, która wymaga klucza interfejsu API specyficznego dla funkcji. Można go również ustawić na Administracja, aby użyć globalnego klucza "głównego" lub anonimowego, aby wskazać, że żaden klucz nie jest wymagany. Poziom autoryzacji można również zmienić po utworzeniu za pośrednictwem właściwości funkcji.

Ponieważ podczas tworzenia tej funkcji określono funkcję , należy podać klucz podczas wysyłania żądania HTTP. Można wysłać go jako parametr ciągu zapytania o nazwie code. Możesz też użyć preferowanej metody i przekazać ją jako nagłówek HTTP o nazwie x-functions-key.

  1. Aby znaleźć funkcję i klucze główne, w menu Aplikacja funkcji w obszarze Deweloper wybierz pozycję Klucze funkcji. Zostanie otwarte okienko Klucze funkcji dla funkcji.

  2. Domyślnie wartość klucza funkcji jest ukryta. Pokaż domyślną wartość klucza funkcji, wybierając pozycję Pokaż wartość. Skopiuj zawartość pola Wartość do schowka, a następnie zapisz ten klucz w Notatnik lub podobnej aplikacji do późniejszego użycia.

    Screenshot showing the Function Keys pane with the revealed function key highlighted.

  3. Aby przetestować funkcję przy użyciu klucza funkcji, otwórz wiersz polecenia i uruchom polecenie cURL, aby wysłać żądanie HTTP do adresu URL funkcji. Zastąp <your-function-key> ciąg zapisaną wartością klucza funkcji i zastąp <your-https-url> ciąg adresem URL funkcji.

    curl --header "Content-Type: application/json" --header "x-functions-key: <your-function-key>" --request POST --data "{\"name\": \"Azure Function\"}" <your-https-url>
    
  4. Przejrzyj polecenie cURL i sprawdź, czy ma następujące wartości:

    • Dodano wartość nagłówka Content-Type typu application/json.
    • Przekazano klucz funkcji jako wartość nagłówka x-functions-key.
    • Użyto żądania POST.
    • Przekazano funkcję platformy Azure przy użyciu adresu URL funkcji.
  5. Sprawdź dzienniki.

    Okienko Kod i test powinno otworzyć sesję z wyświetlonymi danymi wyjściowymi pliku dziennika (upewnij się, że w menu rozwijanym w górnej części okienka Dzienniki wybrano pozycję Dzienniki systemu plików). Plik dziennika zostanie zaktualizowany o stan żądania, który powinien wyglądać mniej więcej tak:

```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)
```

Dodawanie logiki biznesowej do funkcji

Dodajmy logikę do funkcji, aby sprawdzić odczyty temperatury odbierane i ustawić stan dla każdego odczytu temperatury.

Nasza funkcja oczekuje tablicy odczytów temperatury. Poniższy fragment kodu JSON to przykładowa treść żądania, które wyślemy do naszej funkcji. Każdy wpis reading zawiera identyfikator, znacznik czasu i temperaturę.

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

Zastąpmy domyślny kod w naszej funkcji następującym kodem, aby zaimplementować naszą logikę biznesową.

W okienku funkcji HttpTrigger1 otwórz plik index.js i zastąp go następującym kodem. Po wprowadzeniu tej zmiany na pasku poleceń wybierz pozycję Zapisz , aby zapisać aktualizacje w pliku.

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();
};

Logika, którą dodaliśmy, jest bardzo prosta. Iterujemy przez tablicę i ustawiamy stan JAKO OK, PRZESTROGA lub NIEBEZPIECZEŃSTWO na podstawie wartości pola temperatury. Następnie wysyłamy z powrotem tablicę odczytów z polem stanu dodanym do każdego wpisu.

Zwróć uwagę na Log instrukcje po rozwinięciu obszaru Dzienniki w dolnej części okienka. Po uruchomieniu funkcji te instrukcje dodają komunikaty w oknie Dzienniki.

Otwórz plik run.ps1 i zastąp zawartość następującym kodem. Po wprowadzeniu tej zmiany na pasku poleceń wybierz pozycję Zapisz , aby zapisać aktualizacje w pliku.

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
})

Logika, którą dodaliśmy, jest bardzo prosta. Iterujemy przez tablicę i ustawiamy stan JAKO OK, PRZESTROGA lub NIEBEZPIECZEŃSTWO na podstawie wartości pola temperatury. Następnie wysyłamy z powrotem tablicę odczytów z polem stanu dodanym do każdego wpisu.

Zanotuj wywołania polecenia cmdlet Write-Host. Po uruchomieniu funkcji te instrukcje dodają komunikaty w oknie Dzienniki.

Testowanie naszej logiki biznesowej

Użyjemy funkcji Testowanie/uruchamianie w kodzie dewelopera>i testowaniu, aby przetestować naszą funkcję.

  1. Na karcie Dane wejściowe zastąp zawartość pola tekstowego Treść poniższym kodem, aby utworzyć nasze przykładowe żądanie.

    {
        "readings": [
            {
                "driveGearId": 1,
                "timestamp": 1534263995,
                "temperature": 23
            },
            {
                "driveGearId": 3,
                "timestamp": 1534264048,
                "temperature": 45
            },
            {
                "driveGearId": 18,
                "timestamp": 1534264050,
                "temperature": 55
            }
        ]
    }
    
  2. Wybierz Uruchom. Na karcie Dane wyjściowe zostanie wyświetlony kod odpowiedzi HTTP i zawartość. Aby wyświetlić komunikaty dziennika, otwórz kartę Dzienniki w dolnej części okienka (jeśli nie jest jeszcze otwarty). Poniższa ilustracja przedstawia przykładową odpowiedź w okienku danych wyjściowych oraz komunikaty w okienku Dzienniki.

    Screenshot of the Azure function editor, with the Test and Logs tabs showing.

    Karta Dane wyjściowe pokazuje, że pole stanu zostało poprawnie dodane do każdego z odczytów.

  3. W menu Deweloper po lewej stronie wybierz pozycję Monitor, aby zobaczyć, że żądanie zostało zarejestrowane w aplikacji Szczegółowe informacje. Zostanie wyświetlone okienko Monitor dla funkcji.

    Na karcie Wywołania w okienku są wyświetlane ślady wywołań dla każdego wywołania funkcji. Wybierz wartość Date(UTC) dla jednego z wywołań i wyświetl szczegóły dotyczące wykonywania funkcji.