Szybki start: reagowanie na zmiany bazy danych w usłudze Azure Cosmos DB przy użyciu usługi Azure Functions

W tym przewodniku Quickstart użyjesz Visual Studio Code do utworzenia aplikacji, która reaguje na zmiany w bazie danych NoSQL w usłudze Azure Cosmos DB. Po przetestowaniu kodu lokalnie wdrożysz go w nowej aplikacji funkcji bezserwerowej utworzonej w planie Flex Consumption w usłudze Azure Functions.

Źródło projektu używa rozszerzenia interfejsu wiersza polecenia dewelopera Azure (azd) z Visual Studio Code, aby uprościć inicjowanie i weryfikowanie kodu projektu lokalnie, a także wdrażanie kodu w Azure. To wdrożenie jest zgodne z bieżącymi najlepszymi rozwiązaniami dotyczącymi bezpiecznych i skalowalnych wdrożeń usługi Azure Functions.

Chociaż plan Flex Consumption opiera się na modelu rozliczeń płać za to, z czego korzystasz, ten projekt programistyczny tworzy dodatkowe zasoby platformy Azure, w tym wystąpienie usługi Azure Cosmos DB. Pamiętaj, aby wyczyścić zasoby po zakończeniu, aby uniknąć bieżących opłat.

Ten artykuł obsługuje wersję 4 modelu programowania Node.js dla usługi Azure Functions.

Ten artykuł obsługuje wersję 2 modelu programowania Python dla Azure Functions.

Wymagania wstępne

  • Node.js 22.x lub nowsze. Użyj polecenia node --version, aby sprawdzić swoją wersję.

Inicjowanie projektu

Użyj interfejsu wiersza polecenia dewelopera Azure (azd), aby utworzyć lokalny projekt kodu Azure Functions na podstawie szablonu.

  1. W terminalu uruchom to azd init polecenie, aby utworzyć projekt lokalny na podstawie szablonu:

    azd init --template functions-quickstart-dotnet-azd-cosmosdb -e cosmosdbchanges-dotnet
    

    To polecenie ściąga pliki projektu z repozytorium template i inicjuje projekt w nowym folderze. W azd środowisko służy do utrzymania unikalnego kontekstu wdrożenia dla aplikacji i możesz zdefiniować więcej niż jedno. Jest również częścią nazwy grupy zasobów utworzonej na platformie Azure.

  2. Przejdź do katalogu projektu:

    cd functions-quickstart-dotnet-azd-cosmosdb
    
  1. W terminalu uruchom to azd init polecenie, aby utworzyć projekt lokalny na podstawie szablonu:

    azd init --template functions-quickstart-java-azd-cosmosdb -e cosmosdbchanges-java
    

    To polecenie ściąga pliki projektu z repozytorium template i inicjuje projekt w nowym folderze. W azd środowisko służy do utrzymania unikalnego kontekstu wdrożenia dla aplikacji i możesz zdefiniować więcej niż jedno. Jest również częścią nazwy grupy zasobów utworzonej na platformie Azure.

  2. Przejdź do katalogu projektu:

    cd functions-quickstart-java-azd-cosmosdb
    
  1. W terminalu uruchom to azd init polecenie, aby utworzyć projekt lokalny na podstawie szablonu:

    azd init --template functions-quickstart-javascript-azd-cosmosdb -e cosmosdbchanges-js
    

    To polecenie ściąga pliki projektu z repozytorium template i inicjuje projekt w nowym folderze. W azd środowisko służy do utrzymania unikalnego kontekstu wdrożenia dla aplikacji i możesz zdefiniować więcej niż jedno. Jest również częścią nazwy grupy zasobów utworzonej na platformie Azure.

  2. Przejdź do katalogu projektu:

    cd functions-quickstart-javascript-azd-cosmosdb
    
  1. W terminalu uruchom to azd init polecenie, aby utworzyć projekt lokalny na podstawie szablonu:

    azd init --template functions-quickstart-powershell-azd-cosmosdb -e cosmosdbchanges-ps
    

    To polecenie ściąga pliki projektu z repozytorium template i inicjuje projekt w nowym folderze. W azd środowisko służy do utrzymania unikalnego kontekstu wdrożenia dla aplikacji i możesz zdefiniować więcej niż jedno. Jest również częścią nazwy grupy zasobów utworzonej na platformie Azure.

  2. Przejdź do katalogu projektu:

    cd functions-quickstart-powershell-azd-cosmosdb
    
  1. W terminalu uruchom to azd init polecenie, aby utworzyć projekt lokalny na podstawie szablonu:

    azd init --template functions-quickstart-typescript-azd-cosmosdb -e cosmosdbchanges-ts
    

    To polecenie ściąga pliki projektu z repozytorium template i inicjuje projekt w nowym folderze. W azd środowisko służy do utrzymania unikalnego kontekstu wdrożenia dla aplikacji i możesz zdefiniować więcej niż jedno. Jest również częścią nazwy grupy zasobów utworzonej na platformie Azure.

  2. Przejdź do katalogu projektu:

    cd functions-quickstart-typescript-azd-cosmosdb
    
  1. W terminalu uruchom to azd init polecenie, aby utworzyć projekt lokalny na podstawie szablonu:

    azd init --template functions-quickstart-python-azd-cosmosdb -e cosmosdbchanges-py
    

    To polecenie ściąga pliki projektu z repozytorium template i inicjuje projekt w nowym folderze. W azd środowisko służy do utrzymania unikalnego kontekstu wdrożenia dla aplikacji i możesz zdefiniować więcej niż jedno. Jest również częścią nazwy grupy zasobów utworzonej na platformie Azure.

  2. Przejdź do katalogu projektu:

    cd functions-quickstart-python-azd-cosmosdb
    
  1. Uruchom to polecenie, w zależności od lokalnego systemu operacyjnego, aby udzielić skryptom konfiguracji wymaganych uprawnień:

    Uruchom to polecenie z wystarczającymi uprawnieniami:

    chmod +x ./infra/scripts/*.sh
    
  2. Otwórz projekt w programie Visual Studio Code:

    code .
    

Aby można było uruchomić aplikację lokalnie, należy utworzyć zasoby na platformie Azure. Ten projekt nie używa lokalnej emulacji dla usługi Azure Cosmos DB.

Tworzenie zasobów platformy Azure

Ten projekt jest skonfigurowany, aby użyć polecenia azd provision, aby utworzyć aplikację funkcji w planie Flex Consumption, a także innych wymaganych zasobów Microsoft Azure zgodnych z bieżącymi najlepszymi praktykami.

  1. W programie Visual Studio Code naciśnij F1 , aby otworzyć paletę poleceń, wyszukaj i uruchom polecenie Azure Developer CLI (azd): Sign In with Azure Developer CLI, a następnie zaloguj się przy użyciu konta platformy Azure.

  2. Naciśnij F1 , aby otworzyć paletę poleceń, wyszukaj i uruchom polecenie Azure Developer CLI (azd): Provision Azure resources (provision) , aby utworzyć wymagane zasoby platformy Azure:

  3. Po wyświetleniu monitu w oknie Terminal podaj następujące wymagane parametry wdrożenia:

    Podpowiedź Description
    Wybieranie subskrypcji platformy Azure do użycia Wybierz subskrypcję, w której chcesz utworzyć zasoby.
    parametr lokalizacji wdrożenia Region platformy Azure, w którym ma zostać utworzona grupa zasobów zawierająca nowe zasoby platformy Azure. Wyświetlane są tylko regiony, które obecnie obsługują plan Flex Consumption.
    vnetEnabled parametr wdrożenia Szablon obsługuje tworzenie zasobów wewnątrz sieci wirtualnej, aby uprościć wdrażanie i testowanie, wybierz pozycję False.

    Polecenie azd provision używa odpowiedzi na te wezwania z plikami konfiguracji Bicep w celu utworzenia i skonfigurowania tych wymaganych zasobów platformy Azure, zgodnie z najnowszymi najlepszymi praktykami.

    • Plan taryfowy Flex Consumption i aplikacja funkcji
    • Konto usługi Azure Cosmos DB
    • Azure Storage (wymagane) i Application Insights (zalecane)
    • Zasady dostępu i role dla twojego konta
    • Połączenia między usługami przy użyciu tożsamości zarządzanych (zamiast zapisanych parametrów połączenia)

    Po aprowizacji haki generują również plik local.settings.json wymagany podczas uruchamiania lokalnego. Ten plik zawiera również ustawienia wymagane do nawiązania połączenia z bazą danych usługi Azure Cosmos DB na platformie Azure.

    Wskazówka

    Jeśli wszystkie kroki kończą się niepowodzeniem podczas aprowizacji, możesz ponownie uruchomić azd provision polecenie po rozwiązaniu wszelkich problemów.

    Po pomyślnym zakończeniu polecenia możesz uruchomić kod projektu lokalnie i wyzwolić go w bazie danych usługi Azure Cosmos DB na platformie Azure.

Lokalne uruchamianie funkcji

Program Visual Studio Code integruje się z narzędziami Azure Functions Core , aby umożliwić uruchamianie tego projektu na lokalnym komputerze deweloperów przed opublikowaniem w nowej aplikacji funkcji na platformie Azure.

  1. Naciśnij F1 i w palecie poleceń wyszukaj i uruchom polecenie Azurite: Start.

  2. Aby uruchomić funkcję lokalnie, naciśnij F5 lub ikonę Uruchom i debuguj na pasku działań po lewej stronie. Na panelu Terminal są wyświetlane dane wyjściowe z narzędzi Core Tools. Aplikacja zostanie uruchomiona na panelu Terminal i będzie widoczna nazwa funkcji uruchomionej lokalnie.

    Jeśli masz problemy przy uruchamianiu w systemie Windows, upewnij się, że domyślny terminal programu Visual Studio Code nie jest ustawiony na WSL Bash.

  3. Gdy narzędzia Core Tools nadal działają w terminalu, naciśnij F1 i w palecie poleceń wyszukaj i uruchom polecenie NoSQL: Create Item... , a następnie document-db wybierz zarówno bazę danych, jak i documents kontener.

  4. Zastąp zawartość pliku New Item.json danymi JSON i wybierz pozycję Zapisz:

    {
        "id": "doc1",
        "title": "Sample document",
        "content": "This is a sample document for testing my Azure Cosmos DB trigger in Azure Functions."
    }
    

    Po wybraniu pozycji Zapisz zobaczysz wykonanie funkcji w terminalu, a dokument lokalny zostanie zaktualizowany w celu uwzględnienia metadanych dodanych przez usługę.

  5. Gdy skończysz, naciśnij Ctrl+C w oknie terminala, aby zatrzymać proces func.exe hosta.

Przejrzyj kod (opcjonalnie)

Funkcja jest wyzwalana na podstawie zestawienia zmian w bazie danych NoSQL usługi Azure Cosmos DB.

Te zmienne środowiskowe konfigurują sposób, w jaki wyzwalacz monitoruje strumień zmian.

  • COSMOS_CONNECTION__accountEndpoint: punkt końcowy konta usługi Cosmos DB
  • COSMOS_DATABASE_NAME: nazwa bazy danych do monitorowania
  • COSMOS_CONTAINER_NAME: nazwa kontenera do monitorowania

Te zmienne środowiskowe są tworzone zarówno na platformie Azure (ustawienia aplikacji funkcji), jak i lokalnie (local.settings.json) podczas azd provision operacji.

Zmienna COSMOS_CONNECTION środowiskowa konfiguruje punkt końcowy konta usługi Cosmos DB używany przez wyzwalacz. Ta zmienna środowiskowa jest tworzona zarówno w Azure (ustawienia aplikacji funkcji) jak i lokalnie (local.settings.json) podczas operacji azd provision. Nazwy baz danych i kontenerów są zdefiniowane w konfiguracji wyzwalacza.

Możesz przejrzeć kod definiujący wyzwalacz Azure Cosmos DB:

using System;
using System.Collections.Generic;
using Microsoft.Azure.Functions.Worker;
using Microsoft.Extensions.Logging;

namespace Company.Function
{
    public class CosmosTrigger
    {
        private readonly ILogger _logger;

        public CosmosTrigger(ILoggerFactory loggerFactory)
        {
            _logger = loggerFactory.CreateLogger<CosmosTrigger>();
        }

        [Function("cosmos_trigger")]
        public void Run([CosmosDBTrigger(
            databaseName: "%COSMOS_DATABASE_NAME%",
            containerName: "%COSMOS_CONTAINER_NAME%",
            Connection = "COSMOS_CONNECTION",
            LeaseContainerName = "leases",
            CreateLeaseContainerIfNotExists = true)] IReadOnlyList<MyDocument> input)
        {
            if (input != null && input.Count > 0)
            {
                _logger.LogInformation("Documents modified: " + input.Count);
                _logger.LogInformation("First document Id: " + input[0].id);
            }
        }
    }
    public class MyDocument
    {
        /// <summary>
        /// The unique identifier for the document.
        /// </summary>
        public required string id { get; set; }

        /// <summary>
        /// A text field in the document.
        /// </summary>
        public required string Text { get; set; }

        /// <summary>
        /// A numeric field in the document.
        /// </summary>
        public int Number { get; set; }

        /// <summary>
        /// A boolean field in the document.
        /// </summary>
        public bool Boolean { get; set; }
    }
}

Pełny projekt szablonu można przejrzeć tutaj.

package com.function;

import com.microsoft.azure.functions.ExecutionContext;
import com.microsoft.azure.functions.annotation.CosmosDBTrigger;
import com.microsoft.azure.functions.annotation.FunctionName;

public class CosmosTrigger {

    @FunctionName("cosmos_trigger")
    public void run(
        @CosmosDBTrigger(
            name = "input",
            databaseName = "%COSMOS_DATABASE_NAME%",
            containerName = "%COSMOS_CONTAINER_NAME%",
            connection = "COSMOS_CONNECTION",
            leaseContainerName = "leases",
            createLeaseContainerIfNotExists = true
        ) Object[] items,
        final ExecutionContext context
    ) {
        if (items != null && items.length > 0) {
            context.getLogger().info("Documents modified: " + items.length);
            context.getLogger().info("First document Id: " + items[0].toString());
        }
    }
}

Pełny projekt szablonu można przejrzeć tutaj.

const { app } = require('@azure/functions');

app.cosmosDB('cosmos_trigger', {
    connection: 'COSMOS_CONNECTION',
    databaseName: '%COSMOS_DATABASE_NAME%',
    containerName: '%COSMOS_CONTAINER_NAME%',
    leaseContainerName: 'leases',
    createLeaseContainerIfNotExists: true,
    handler: (documents, context) => {
        if (documents && documents.length > 0) {
            context.log(`Documents modified: ${documents.length}`);
            context.log(`First document Id: ${documents[0].id}`);
        }
    }
});

Pełny projekt szablonu można przejrzeć tutaj.

import { app, InvocationContext } from "@azure/functions";

export async function cosmos_trigger(documents: unknown[], context: InvocationContext): Promise<void> {
    context.log(`Cosmos DB function processed ${documents.length} documents`);

    if (documents && documents.length > 0) {
        for (const doc of documents) {
            context.log(`First document: ${JSON.stringify(doc)}`);
            if (doc && typeof doc === "object" && "id" in doc) {
                context.log(`First document id: ${(doc as { id?: string }).id}`);
            }
        }
    } else {
        context.log("No documents found.");
    }
}


app.cosmosDB('cosmos_trigger', {
    connection: 'COSMOS_CONNECTION',
    databaseName: 'documents-db',
    containerName: 'documents',
    createLeaseContainerIfNotExists: true,
    handler: cosmos_trigger
});

Pełny projekt szablonu można przejrzeć tutaj.

Wyzwalacz jest zdefiniowany w tym pliku function.json :

{
  "bindings": [
    {
      "type": "cosmosDBTrigger",
      "name": "InputDocuments",
      "direction": "in",
      "databaseName": "%COSMOS_DATABASE_NAME%",
      "containerName": "%COSMOS_CONTAINER_NAME%",
      "connection": "COSMOS_CONNECTION",
      "leaseContainerName": "leases",
      "createLeaseContainerIfNotExists": true
    }
  ]
}

Poniższy kod jest wykonywany po uruchomieniu wyzwalacza:

param($InputDocuments, $TriggerMetadata)

if ($InputDocuments -and $InputDocuments.Count -gt 0) {
    Write-Host "Documents modified: $($InputDocuments.Count)"
    Write-Host "First document Id: $($InputDocuments[0].id)"
}

Pełny projekt szablonu można przejrzeć tutaj.

import json
import logging
import os

import azure.functions as func

app = func.FunctionApp()


@app.cosmos_db_trigger(
    arg_name="documents",
    container_name=os.environ.get("COSMOS_CONTAINER_NAME"),
    database_name=os.environ.get("COSMOS_DATABASE_NAME"),
    connection="COSMOS_CONNECTION",
    lease_container_name="leases",
    lease_container_prefix="py-latest-version",
    change_feed_mode=func.CosmosDBChangeFeedMode.LATEST_VERSION,
)
def cosmos_trigger(documents: func.DocumentList):
    logging.info("Python CosmosDB triggered.")
    logging.info(f"Documents modified: {len(documents)}")
    if documents:
        for doc in documents:
            logging.info(f"First document: {doc.to_json()}")
            logging.info(f"First document id: {doc.get('id')}")
    else:
        logging.info("No documents found.")


def _get_change_details(change: func.Document):
    payload = dict(change)
    current = payload.get("current")
    metadata = payload.get("metadata")
    current_document = current if isinstance(current, dict) else payload
    change_metadata = metadata if isinstance(metadata, dict) else {}

    operation_type = change_metadata.get("operationType", "unknown")
    document_id = (
        current_document.get("id")
        or change_metadata.get("id")
        or payload.get("id")
    )
    lsn = change_metadata.get("lsn") or payload.get("_lsn")
    time_to_live_expired = change_metadata.get("timeToLiveExpired", False)
    return operation_type, document_id, lsn, time_to_live_expired


@app.cosmos_db_trigger(
    arg_name="changes",
    container_name=os.environ.get("COSMOS_CONTAINER_NAME"),
    database_name=os.environ.get("COSMOS_DATABASE_NAME"),
    connection="COSMOS_CONNECTION",
    lease_container_name="leases",
    lease_container_prefix="py-full-fidelity",
    change_feed_mode=func.CosmosDBChangeFeedMode.ALL_VERSIONS_AND_DELETES,
)
def cosmos_full_fidelity_trigger(changes: func.DocumentList):
    logging.info("Python Cosmos DB full-fidelity trigger processed %d changes.", len(changes))

    for index, change in enumerate(changes):
        operation_type, document_id, lsn, time_to_live_expired = (
            _get_change_details(change)
        )
        logging.info(
            "FullFidelity change index=%d operation=%s id=%s lsn=%s",
            index,
            operation_type,
            document_id,
            lsn,
        )
        if time_to_live_expired:
            logging.info("Document %s was deleted because its TTL expired.", document_id)
        logging.info(
            "FullFidelity raw[%d]=%s",
            index,
            json.dumps(dict(change), default=str),
        )

Pełny projekt szablonu można przejrzeć tutaj.

Po przejrzeniu i zweryfikowaniu kodu funkcji lokalnie nadszedł czas na opublikowanie projektu na platformie Azure.

Wdrażanie na platformie Azure

Możesz uruchomić azd deploy polecenie z poziomu programu Visual Studio Code, aby wdrożyć kod projektu w już zaaprowizowanych zasobach na platformie Azure.

  1. Naciśnij F1 , aby otworzyć paletę poleceń.

  2. Wyszukaj i uruchom polecenie Azure Developer CLI (azd): Deploy to Azure (deploy).

    Polecenie azd deploy pakuje i wdraża kod w kontenerze wdrażania. Aplikacja jest następnie uruchamiana i działa we wdrożonym pakiecie.

    Po pomyślnym zakończeniu działania polecenia aplikacja jest uruchomiona na platformie Azure.

Wywoływanie funkcji na platformie Azure

  1. W programie Visual Studio Code naciśnij F1 , a następnie w palecie poleceń wyszukaj i uruchom polecenie Azure: Open in portal, wybierz pozycję Function app, a następnie wybierz nową aplikację. W razie potrzeby zaloguj się przy użyciu konta platformy Azure.

    To polecenie otwiera nową aplikację funkcji w portalu Azure.

  2. Na karcie Przegląd na stronie głównej wybierz nazwę swojej aplikacji funkcji, a następnie kartę Dzienniki.

  3. NoSQL: Create Item Użyj polecenia w programie Visual Studio Code, aby ponownie dodać dokument do kontenera tak jak poprzednio.

  4. Sprawdź ponownie, czy funkcja zostanie wyzwolona przez aktualizację w monitorowanym kontenerze.

Ponowne wdrażanie kodu

Możesz uruchomić azd deploy polecenie tyle razy, ile trzeba wdrożyć aktualizacje kodu w aplikacji funkcji.

Uwaga / Notatka

Wdrożone pliki kodu są zawsze zastępowane przez najnowszy pakiet wdrożeniowy.

Początkowe odpowiedzi na polecenia azd oraz wszelkie zmienne środowiskowe wygenerowane przez azd są przechowywane lokalnie w środowisku o podanej nazwie. Użyj polecenia , azd env get-values aby przejrzeć wszystkie zmienne w środowisku, które zostały użyte podczas tworzenia zasobów platformy Azure.

Uprzątnij zasoby

Po zakończeniu pracy z aplikacją funkcji i powiązanymi zasobami możesz użyć tego polecenia, aby usunąć aplikację funkcji i powiązane z nią zasoby z platformy Azure i uniknąć ponoszenia dodatkowych kosztów:

azd down --no-prompt

Uwaga / Notatka

Opcja --no-prompt powoduje azd usunięcie grupy zasobów bez potwierdzenia.

To polecenie nie ma wpływu na lokalny projekt kodu.