Inicio rápido: Respuesta a los cambios de base de datos en Azure Cosmos DB mediante Azure Functions

En este inicio rápido, usará Visual Studio Code para compilar una aplicación que responda a los cambios de base de datos en una base de datos No SQL en Azure Cosmos DB. Después de probar el código localmente, se implementa en una nueva aplicación de funciones sin servidor que se crea en ejecución en un plan de consumo flexible en Azure Functions.

El origen del proyecto usa la extensión Azure Developer CLI (azd) con Visual Studio Code para simplificar la inicialización y comprobación del código del proyecto localmente, así como la implementación del código en Azure. Esta implementación sigue los procedimientos recomendados actuales para implementaciones seguras y escalables de Azure Functions.

Aunque el plan de consumo flexible sigue un pay-for-what-you-use modelo de facturación, este proyecto de código crea recursos de Azure adicionales, incluida una instancia de Azure Cosmos DB. Asegúrese de limpiar los recursos cuando haya terminado, para evitar cargos en curso.

En este artículo se admite la versión 4 del modelo de programación de Node.js para Azure Functions.

En este artículo se admite la versión 2 del modelo de programación de Python para Azure Functions.

Prerrequisitos

  • Node.js 18.x o superior. Use el comando node --version para comprobar la versión.

Inicialización del proyecto

Use la CLI para desarrolladores de Azure (azd) para crear un proyecto de código de Azure Functions local a partir de una plantilla.

  1. Desde un terminal, ejecute este azd init comando para crear un proyecto local a partir de la plantilla:

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

    Este comando extrae los archivos del proyecto del repositorio template e inicializa el proyecto en una nueva carpeta. En azd, el entorno se usa para mantener un contexto de implementación único para la aplicación y puede definir más de uno. También forma parte del nombre del grupo de recursos que crea en Azure.

  2. Cambie al directorio del proyecto:

    cd functions-quickstart-dotnet-azd-cosmosdb
    
  1. Desde un terminal, ejecute este azd init comando para crear un proyecto local a partir de la plantilla:

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

    Este comando extrae los archivos del proyecto del repositorio template e inicializa el proyecto en una nueva carpeta. En azd, el entorno se usa para mantener un contexto de implementación único para la aplicación y puede definir más de uno. También forma parte del nombre del grupo de recursos que crea en Azure.

  2. Cambie al directorio del proyecto:

    cd functions-quickstart-java-azd-cosmosdb
    
  1. Desde un terminal, ejecute este azd init comando para crear un proyecto local a partir de la plantilla:

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

    Este comando extrae los archivos del proyecto del repositorio template e inicializa el proyecto en una nueva carpeta. En azd, el entorno se usa para mantener un contexto de implementación único para la aplicación y puede definir más de uno. También forma parte del nombre del grupo de recursos que crea en Azure.

  2. Cambie al directorio del proyecto:

    cd functions-quickstart-javascript-azd-cosmosdb
    
  1. Desde un terminal, ejecute este azd init comando para crear un proyecto local a partir de la plantilla:

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

    Este comando extrae los archivos del proyecto del repositorio template e inicializa el proyecto en una nueva carpeta. En azd, el entorno se usa para mantener un contexto de implementación único para la aplicación y puede definir más de uno. También forma parte del nombre del grupo de recursos que crea en Azure.

  2. Cambie al directorio del proyecto:

    cd functions-quickstart-powershell-azd-cosmosdb
    
  1. Desde un terminal, ejecute este azd init comando para crear un proyecto local a partir de la plantilla:

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

    Este comando extrae los archivos del proyecto del repositorio template e inicializa el proyecto en una nueva carpeta. En azd, el entorno se usa para mantener un contexto de implementación único para la aplicación y puede definir más de uno. También forma parte del nombre del grupo de recursos que crea en Azure.

  2. Cambie al directorio del proyecto:

    cd functions-quickstart-typescript-azd-cosmosdb
    
  1. Desde un terminal, ejecute este azd init comando para crear un proyecto local a partir de la plantilla:

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

    Este comando extrae los archivos del proyecto del repositorio template e inicializa el proyecto en una nueva carpeta. En azd, el entorno se usa para mantener un contexto de implementación único para la aplicación y puede definir más de uno. También forma parte del nombre del grupo de recursos que crea en Azure.

  2. Cambie al directorio del proyecto:

    cd functions-quickstart-python-azd-cosmosdb
    
  1. Ejecute este comando, en función del sistema operativo local, para conceder a los scripts de configuración los permisos necesarios:

    Ejecute este comando con privilegios suficientes:

    chmod +x ./infra/scripts/*.sh
    
  2. Abra el proyecto en Visual Studio Code:

    code .
    

Para poder ejecutar la aplicación localmente, debe crear los recursos en Azure. Este proyecto no usa la emulación local para Azure Cosmos DB.

Creación de recursos de Azure

Este proyecto está configurado para usar el azd provision comando para crear una aplicación de funciones en un plan de consumo flexible, junto con otros recursos de Azure necesarios que siguen los procedimientos recomendados actuales.

  1. En Visual Studio Code, presione F1 para abrir la paleta de comandos, busque y ejecute el comando Azure Developer CLI (azd): Sign In with Azure Developer CLIy, a continuación, inicie sesión con su cuenta de Azure.

  2. Presione F1 para abrir la paleta de comandos, busque y ejecute el comando Azure Developer CLI (azd): Provision Azure resources (provision) para crear los recursos de Azure necesarios:

  3. Cuando se le solicite en la ventana Terminal, proporcione estos parámetros de implementación necesarios:

    Pronto Description
    Selección de una suscripción de Azure que se va a usar Elija la suscripción en la que desea que se creen los recursos.
    parámetro de implementación de ubicación Región de Azure en la que se va a crear el grupo de recursos que contiene los nuevos recursos de Azure. Solo se muestran las regiones que admiten actualmente el Plan de consumo flexible.
    Parámetro de implementación vnetEnabled Aunque la plantilla admite la creación de recursos dentro de una red virtual, para simplificar la implementación y las pruebas, elija False.

    El azd provision comando usa la respuesta a estos mensajes con los archivos de configuración de Bicep para crear y configurar estos recursos de Azure necesarios, siguiendo los procedimientos recomendados más recientes:

    • Plan de consumo flexible y aplicación de funciones
    • Cuenta de Azure Cosmos DB
    • Azure Storage (obligatorio) y Application Insights (recomendado)
    • Directivas y roles de acceso para la cuenta
    • Conexiones de servicio a servicio mediante identidades administradas (en lugar de cadenas de conexión almacenadas)

    Los enlaces posteriores al aprovisionamiento también generan el archivo local.settings.json necesario al ejecutarse localmente. Este archivo también contiene la configuración necesaria para conectarse a la base de datos de Azure Cosmos DB en Azure.

    Sugerencia

    Si se produce un error en los pasos durante el aprovisionamiento, puede volver a ejecutar el azd provision comando después de resolver los problemas.

    Una vez completado correctamente el comando, puede ejecutar el código del proyecto localmente y desencadenarlo en la base de datos de Azure Cosmos DB en Azure.

Ejecución local de la función

Visual Studio Code se integra con azure Functions Core Tools para permitirle ejecutar este proyecto en el equipo de desarrollo local antes de publicar en la nueva aplicación de funciones en Azure.

  1. Presione F1 y, en la paleta de comandos, busque y ejecute el comando Azurite: Start.

  2. Para iniciar la función localmente, presione F5 o el icono Ejecutar y depurar en la barra de actividad del lado izquierdo. El panel Terminal muestra la salida de Core Tools. La aplicación se inicia en el panel Terminal y puede ver el nombre de la función que se ejecuta localmente.

    Si tiene problemas para ejecutarlo en Windows, asegúrese de que el terminal predeterminado de Visual Studio Code no esté establecido en WSL Bash.

  3. Con Core Tools todavía ejecutándose en Terminal, presione F1 y, en la paleta de comandos, busque y ejecute el comando NoSQL: Create Item... y seleccione la document-db base de datos y el documents contenedor.

  4. Reemplace el contenido del nuevo archivo Item.json por estos datos JSON y seleccione Guardar:

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

    Después de seleccionar Guardar, verá la ejecución de la función en el terminal y el documento local se actualiza para incluir los metadatos agregados por el servicio.

  5. Cuando haya terminado, presione Ctrl+C en la ventana del terminal para detener el proceso de host de func.exe.

Revisión del código (opcional)

La función se desencadena en función de la fuente de cambios en una base de datos NoSQL de Azure Cosmos DB.

Estas variables de entorno configuran cómo el desencadenador supervisa la fuente de cambios:

  • COSMOS_CONNECTION__accountEndpoint: el punto de conexión de la cuenta de Cosmos DB
  • COSMOS_DATABASE_NAME: el nombre de la base de datos que se va a supervisar.
  • COSMOS_CONTAINER_NAME: el nombre del contenedor que se va a supervisar.

Estas variables de entorno se crean automáticamente en Azure (configuración de la aplicación de funciones) y localmente (local.settings.json) durante la azd provision operación.

La COSMOS_CONNECTION variable de entorno configura el punto de conexión de la cuenta de Cosmos DB que usa el desencadenador. Esta variable de entorno se crea automáticamente tanto en Azure (configuración de la aplicación de funciones) como localmente (local.settings.json) durante la operación de azd provision. Los nombres de base de datos y contenedor se definen en la configuración del desencadenador.

Puede revisar el código que define el desencadenador de 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; }
    }
}

Puede revisar el proyecto de plantilla completo here.

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

Puede revisar el proyecto de plantilla completo here.

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

Puede revisar el proyecto de plantilla completo here.

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

Puede revisar el proyecto de plantilla completo here.

El desencadenador se define en este archivo function.json :

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

El código siguiente se ejecuta cuando se ejecuta el desencadenador:

param($InputDocuments, $TriggerMetadata)

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

Puede revisar el proyecto de plantilla completo here.

import os
import azure.functions as func
import logging

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",
    create_lease_container_if_not_exists="true",
)
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.")

Puede revisar el proyecto de plantilla completo here.

Después de revisar y comprobar el código de función localmente, es el momento de publicar el proyecto en Azure.

Implementación en Azure

Puede ejecutar el azd deploy comando desde Visual Studio Code para implementar el código del proyecto en los recursos ya aprovisionados en Azure.

  1. Pulsa F1 para abrir la paleta de comandos.

  2. Busque y ejecute el comando Azure Developer CLI (azd): Deploy to Azure (deploy).

    El azd deploy comando empaqueta e implementa el código en el contenedor de implementación. A continuación, la aplicación se inicia y se ejecuta en el paquete implementado.

    Una vez completado correctamente el comando, la aplicación se ejecuta en Azure.

Invocación de la función en Azure

  1. En Visual Studio Code, presione F1 y, en la paleta de comandos, busque y ejecute el comando Azure: Open in portal, seleccione Function appy elija la nueva aplicación. Inicie sesión con su cuenta de Azure, si es necesario.

    Este comando abre la nueva aplicación de funciones en Azure Portal.

  2. En la pestaña Información general de la página principal, seleccione el nombre de la aplicación de funciones y, a continuación, la pestaña Registros .

  3. Use el NoSQL: Create Item comando en Visual Studio Code para agregar de nuevo un documento al contenedor como antes.

  4. Compruebe de nuevo que la función se desencadene mediante una actualización en el contenedor supervisado.

Reimplementación del código

Puede ejecutar el azd deploy comando tantas veces como necesite para implementar actualizaciones de código en la aplicación de funciones.

Nota:

El paquete de implementación más reciente siempre sobrescribe los archivos de código implementados.

Las respuestas iniciales a azd mensajes y las variables de entorno generadas por azd se almacenan localmente en el entorno con nombre. Use el comando azd env get-values para revisar todas las variables del entorno que se usaron al crear recursos de Azure.

Limpieza de recursos

Cuando haya terminado de trabajar con la aplicación de funciones y los recursos relacionados, puede usar este comando para eliminar la aplicación de funciones y sus recursos relacionados de Azure y evitar incurrir en costos adicionales:

azd down --no-prompt

Nota:

La --no-prompt opción indica azd que elimine el grupo de recursos sin una confirmación de usted.

Este comando no afecta al proyecto de código local.