Conectar o Azure Functions ao Azure Cosmos DB usando o Visual Studio Code

O Azure Functions permite que você conecte os serviços do Azure e outros recursos a funções sem precisar escrever seu próprio código de integração. Essas ligações, que representam entrada e saída, são declaradas dentro da definição de função. Os dados de enlaces são fornecidos à função como parâmetros. Um gatilho é um tipo especial de ligação de entrada. Embora uma função tenha apenas um gatilho, ela pode ter várias ligações de entrada e saída. Para saber mais, consulte Conceitos de acionadores e associações do Azure Functions.

Este artigo mostra como usar o Visual Studio Code para conectar o Azure Cosmos DB à função criada no artigo de início rápido anterior. A associação de saída que você adiciona a essa função grava dados da solicitação HTTP em um documento JSON armazenado em um contêiner do Azure Cosmos DB.

Antes de começar, você deve concluir o guia de início rápido: Criar uma função C# no Azure usando o Visual Studio Code. Se você já limpou recursos no final desse artigo, siga as etapas novamente para recriar o aplicativo de função e os recursos relacionados no Azure.

Antes de começar, você deve concluir o guia de início rápido: Criar uma função JavaScript no Azure usando o Visual Studio Code. Se você já limpou recursos no final desse artigo, siga as etapas novamente para recriar o aplicativo de função e os recursos relacionados no Azure.

Nota

Atualmente, este artigo suporta apenas Node.js v3 para funções.

Antes de começar, você deve concluir o início rápido: Criar uma função Python no Azure usando o Visual Studio Code. Se você já limpou recursos no final desse artigo, siga as etapas novamente para recriar o aplicativo de função e os recursos relacionados no Azure.

Configurar o seu ambiente

Antes de começar, certifique-se de instalar a extensão de Bancos de Dados do Azure para Visual Studio Code.

Criar sua conta do Azure Cosmos DB

Agora, você cria uma conta do Azure Cosmos DB como um tipo de conta sem servidor. Esse modo baseado no consumo torna o Azure Cosmos DB uma opção forte para cargas de trabalho sem servidor.

  1. No Visual Studio Code, selecione View>Command Palette... e, em seguida, na paleta de comandos, procure por Azure Databases: Create Server...

  2. Forneça as seguintes informações nos pedidos:

    Pedido Seleção
    Selecione um Servidor de Banco de Dados do Azure Escolha Core (NoSQL) para criar um banco de dados de documentos que você pode consultar usando uma sintaxe SQL ou um Query Copilot (Preview) convertendo prompts de linguagem natural em consultas. Saiba mais sobre o Azure Cosmos DB.
    Nome da conta Introduza um nome exclusivo para identificar a sua conta do Azure Cosmos DB. O nome da conta pode usar apenas letras minúsculas, números e hífenes (-), e deve ter entre 3 e 31 caracteres.
    Selecione um modelo de capacidade Selecione Serverless para criar uma conta no modo serverless .
    Selecionar um grupo de recursos para novos recursos Escolha o grupo de recursos onde você criou seu aplicativo de função no artigo anterior.
    Selecione um local para novos recursos Selecione a localização geográfica para alojar a sua conta do Azure Cosmos DB. Use o local mais próximo de você ou de seus usuários para obter o acesso mais rápido aos seus dados.

    Depois que sua nova conta for provisionada, uma mensagem será exibida na área de notificação.

Criar um banco de dados e um contêiner do Azure Cosmos DB

  1. Selecione o ícone do Azure na barra de atividades, expanda Recursos>do Azure Cosmos DB, clique com o botão direito do mouse (Ctrl+selecione no macOS) em sua conta e selecione Criar banco de dados....

  2. Forneça as seguintes informações nos pedidos:

    Pedido Seleção
    Nome da base de dados Escreva my-database.
    Insira e ID para a sua coleção Escreva my-container.
    Insira a chave de partição para a coleção Digite /id como a chave de partição.
  3. Selecione OK para criar o contêiner e o banco de dados.

Atualize as configurações do aplicativo de função

No artigo de início rápido anterior, você criou um aplicativo de função no Azure. Neste artigo, você atualiza seu aplicativo para gravar documentos JSON no contêiner do Azure Cosmos DB que você criou. Para se conectar à sua conta do Azure Cosmos DB, você deve adicionar sua cadeia de conexão às configurações do aplicativo. Em seguida, baixe a nova configuração para seu arquivo de local.settings.json para que possa se conectar à sua conta do Azure Cosmos DB ao executar localmente.

  1. No Visual Studio Code, clique com o botão direito do mouse (Ctrl+select no macOS) em sua nova conta do Azure Cosmos DB e selecione Copiar Cadeia de Conexão.

    Copiando a cadeia de conexão do Azure Cosmos DB

  2. Prima F1 para abrir a paleta de comandos e, em seguida, procure e execute o comando Azure Functions: Add New Setting....

  3. Escolha o aplicativo de função que você criou no artigo anterior. Forneça as seguintes informações nos pedidos:

    Pedido Seleção
    Insira o nome da nova configuração do aplicativo Escreva CosmosDbConnectionSetting.
    Insira o valor para "CosmosDbConnectionSetting" Cole a cadeia de conexão da sua conta do Azure Cosmos DB copiada. Você também pode configurar a identidade do Microsoft Entra como uma alternativa.

    Isso cria uma configuração de aplicativo chamada conexão CosmosDbConnectionSetting em seu aplicativo de função no Azure. Agora, você pode baixar essa configuração para seu arquivo local.settings.json.

  4. Pressione F1 novamente para abrir a paleta de comandos, procure e execute o comando Azure Functions: Download Remote Settings....

  5. Escolha o aplicativo de função que você criou no artigo anterior. Selecione Sim para todos para substituir as configurações locais existentes.

Isso baixa toda a configuração do Azure para seu projeto local, incluindo a nova configuração de cadeia de conexão. A maioria das configurações baixadas não é usada quando executada localmente.

Registar as extensões de enlace

Como você está usando uma associação de saída do Azure Cosmos DB, você deve ter a extensão de ligações correspondente instalada antes de executar o projeto.

Exceto para gatilhos HTTP e timer, as ligações são implementadas como pacotes de extensão. Execute o seguinte comando dotnet add package na janela Terminal para adicionar o pacote de extensão do Azure Cosmos DB ao seu projeto.

dotnet add package Microsoft.Azure.Functions.Worker.Extensions.CosmosDB

Seu projeto foi configurado para usar pacotes de extensão, que instalam automaticamente um conjunto predefinido de pacotes de extensão.

O uso de pacotes de extensão é habilitado no arquivo host.json na raiz do projeto, que aparece da seguinte maneira:

{
  "version": "2.0",
  "logging": {
    "applicationInsights": {
      "samplingSettings": {
        "isEnabled": true,
        "excludedTypes": "Request"
      }
    }
  },
  "extensionBundle": {
    "id": "Microsoft.Azure.Functions.ExtensionBundle",
    "version": "[4.*, 5.0.0)"
  },
  "concurrency": {
    "dynamicConcurrencyEnabled": true,
    "snapshotPersistenceEnabled": true
  },
  "extensions": {
    "cosmosDB": {
      "connectionMode": "Gateway"
    }
  }
}

Seu projeto foi configurado para usar pacotes de extensão, que instalam automaticamente um conjunto predefinido de pacotes de extensão.

O uso de pacotes de extensão é habilitado no arquivo host.json na raiz do projeto, que aparece da seguinte maneira:

{
  "version": "2.0",
  "extensionBundle": {
    "id": "Microsoft.Azure.Functions.ExtensionBundle",
    "version": "[3.*, 4.0.0)"
  } 
}

Agora, você pode adicionar a associação de saída do Azure Cosmos DB ao seu projeto.

Adicionar um enlace de saída

Em um projeto de biblioteca de classes C#, as associações são definidas como atributos de ligação no método de função.

Abra o arquivo de projeto HttpExample.cs e adicione as seguintes classes:

public class MultiResponse
{
    [CosmosDBOutput("my-database", "my-container",
        Connection = "CosmosDbConnectionSetting", CreateIfNotExists = true)]
    public MyDocument Document { get; set; }
    public HttpResponseData HttpResponse { get; set; }
}
public class MyDocument {
    public string id { get; set; }
    public string message { get; set; }
}

A MyDocument classe define um objeto que é gravado no banco de dados. A cadeia de conexão para a conta de armazenamento é definida pela Connection propriedade. Nesse caso, você pode omitir Connection porque já está usando a conta de armazenamento padrão.

A MultiResponse classe permite que você grave na coleção especificada no Azure Cosmos DB e retorne uma mensagem de êxito HTTP. Como você precisa retornar um MultiResponse objeto, você também precisa atualizar a assinatura do método.

Atributos específicos especificam o nome do contêiner e o nome de seu banco de dados pai. A cadeia de conexão para sua conta do Azure Cosmos DB é definida pelo CosmosDbConnectionSetting.

Os atributos de vinculação são definidos diretamente no código da função. A configuração de saída do Azure Cosmos DB descreve os campos necessários para uma associação de saída do Azure Cosmos DB.

Para esse MultiResponse cenário, você precisa adicionar uma ligação de extraOutputs saída para a função.

app.http('HttpExample', {
  methods: ['GET', 'POST'],
  extraOutputs: [sendToCosmosDb],
  handler: async (request, context) => {

Adicione as seguintes propriedades à configuração de ligação:

const sendToCosmosDb = output.cosmosDB({
  databaseName: 'my-database',
  containerName: 'my-container',
  createIfNotExists: false,
  connection: 'CosmosDBConnectionString',
});

Os atributos de vinculação são definidos diretamente no arquivo function_app.py . Use o decorador cosmos_db_output para adicionar uma associação de saída do Azure Cosmos DB:

@app.cosmos_db_output(arg_name="outputDocument", database_name="my-database", 
    container_name="my-container", connection="CosmosDbConnectionSetting")

Neste código, arg_name identifica o parâmetro de associação referenciado em seu código database_name e container_name são os nomes de banco de dados e coleção nos quais a associação grava, e connection é o nome de uma configuração de aplicativo que contém a cadeia de conexão para a conta do Azure Cosmos DB, que está na CosmosDbConnectionSetting configuração no arquivo local.settings.json .

Adicione código que utiliza o enlace de saída

Substitua o método Run existente pelo seguinte código:

[Function("HttpExample")]
public static MultiResponse Run([HttpTrigger(AuthorizationLevel.Anonymous, "get", "post")] HttpRequestData req,
    FunctionContext executionContext)
{
    var logger = executionContext.GetLogger("HttpExample");
    logger.LogInformation("C# HTTP trigger function processed a request.");

    var message = "Welcome to Azure Functions!";

    var response = req.CreateResponse(HttpStatusCode.OK);
    response.Headers.Add("Content-Type", "text/plain; charset=utf-8");
    response.WriteString(message);

    // Return a response to both HTTP trigger and Azure Cosmos DB output binding.
    return new MultiResponse()
    {
         Document = new MyDocument
        {
            id = System.Guid.NewGuid().ToString(),
            message = message
        },
        HttpResponse = response
    };
}

Adicione código que usa o extraInputs objeto de vinculação de saída para context enviar um documento JSON para a função de vinculação de saída nomeada, sendToCosmosDb. Adicione este código antes da return instrução.

context.extraOutputs.set(sendToCosmosDb, {
  // create a random ID
  id:
    new Date().toISOString() + Math.random().toString().substring(2, 10),
  name: name,
});

Neste ponto, sua função deve ter a seguinte aparência:

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

const sendToCosmosDb = output.cosmosDB({
  databaseName: 'my-database',
  containerName: 'my-container',
  createIfNotExists: false,
  connection: 'CosmosDBConnectionString',
});

app.http('HttpExampleToCosmosDB', {
  methods: ['GET', 'POST'],
  extraOutputs: [sendToCosmosDb],
  handler: async (request, context) => {
    try {
      context.log(`Http function processed request for url "${request.url}"`);

      const name = request.query.get('name') || (await request.text());

      if (!name) {
        return { status: 404, body: 'Missing required data' };
      }

      // Output to Database
      context.extraOutputs.set(sendToCosmosDb, {
        // create a random ID
        id:
          new Date().toISOString() + Math.random().toString().substring(2, 10),
        name: name,
      });

      const responseMessage = name
        ? 'Hello, ' +
          name +
          '. This HTTP triggered function executed successfully.'
        : 'This HTTP triggered function executed successfully. Pass a name in the query string or in the request body for a personalized response.';

      // Return to HTTP client
      return { body: responseMessage };
    } catch (error) {
      context.log(`Error: ${error}`);
      return { status: 500, body: 'Internal Server Error' };
    }
  },
});

Esse código agora retorna um MultiResponse objeto que contém um documento e uma resposta HTTP.

Atualize HttpExample\function_app.py para corresponder ao código a seguir. Adicione o outputDocument parâmetro à definição da função e outputDocument.set() sob a if name: instrução:

import azure.functions as func
import logging

app = func.FunctionApp()

@app.function_name(name="HttpTrigger1")
@app.route(route="hello", auth_level=func.AuthLevel.ANONYMOUS)
@app.queue_output(arg_name="msg", queue_name="outqueue", connection="AzureWebJobsStorage")
@app.cosmos_db_output(arg_name="outputDocument", database_name="my-database", container_name="my-container", connection="CosmosDbConnectionSetting")
def test_function(req: func.HttpRequest, msg: func.Out[func.QueueMessage],
    outputDocument: func.Out[func.Document]) -> func.HttpResponse:
     logging.info('Python HTTP trigger function processed a request.')
     logging.info('Python Cosmos DB trigger function processed a request.')
     name = req.params.get('name')
     if not name:
        try:
            req_body = req.get_json()
        except ValueError:
            pass
        else:
            name = req_body.get('name')

     if name:
        outputDocument.set(func.Document.from_dict({"id": name}))
        msg.set(name)
        return func.HttpResponse(f"Hello {name}!")
     else:
        return func.HttpResponse(
                    "Please pass a name on the query string or in the request body",
                    status_code=400
                )

O documento {"id": "name"} é criado na coleção de banco de dados especificada na associação.

Executar a função localmente

O Visual Studio Code integra-se com as ferramentas principais do Azure Functions para permitir que você execute este projeto em seu computador de desenvolvimento local antes de publicar no Azure. Se você ainda não tiver o Core Tools instalado localmente, você será solicitado a instalá-lo na primeira vez que executar seu projeto.

  1. Para chamar sua função, pressione F5 para iniciar o projeto de aplicativo de função. O painel Terminal exibe a saída das Ferramentas Principais. Seu aplicativo é iniciado no painel Terminal . Você pode ver o ponto de extremidade de URL da sua função acionada por HTTP em execução localmente.

    Captura de tela da saída Visual Studio Code da função Local.

    Se você ainda não tiver o Core Tools instalado, selecione Instalar para instalar o Core Tools quando solicitado.
    Se você tiver problemas para executar no Windows, verifique se o terminal padrão do Visual Studio Code não está definido como WSL Bash.

  2. Com as Ferramentas Principais em execução, vá para a área Azure: Funções . Em Funções, expanda Funções do Projeto>Local. Clique com o botão direito do mouse (Windows) ou Ctrl - clique em (macOS) na HttpExample função e escolha Executar função agora....

    Captura de tela da função de execução agora do Visual Studio Code.

  3. No corpo da solicitação Enter, pressione Enter para enviar uma mensagem de solicitação para sua função.

  4. Quando a função é executada localmente e retorna uma resposta, uma notificação é gerada no Visual Studio Code. As informações sobre a execução da função são mostradas no painel Terminal .

  5. Pressione Ctrl + C para parar as ferramentas principais e desconectar o depurador.

Executar a função localmente

  1. Como no artigo anterior, pressione F5 para iniciar o projeto de aplicativo de função e as Ferramentas Principais.

  2. Com as Ferramentas Principais em execução, vá para a área Azure: Funções . Em Funções, expanda Funções do Projeto>Local. Clique com o botão direito do rato (Ctrl-clique no Mac) na HttpExample função e escolha Executar Função Agora....

    Execute a função agora a partir do Visual Studio Code

  3. Em Inserir corpo da solicitação, você verá o valor do corpo da mensagem da solicitação de { "name": "Azure" }. Prima Enter para enviar esta mensagem de pedido para a sua função.

  4. Depois que uma resposta for retornada, pressione Ctrl + C para parar as Ferramentas Principais.

Verificar se um documento JSON foi criado

  1. No portal do Azure, volte para sua conta do Azure Cosmos DB e selecione Data Explorer.

  2. Expanda o banco de dados e o contêiner e selecione Itens para listar os documentos criados no contêiner.

  3. Verifique se um novo documento JSON foi criado pela associação de saída.

    Verificando se um novo documento foi criado no contêiner do Azure Cosmos DB

Reimplantar e verificar o aplicativo atualizado

  1. No Visual Studio Code, pressione F1 para abrir a paleta de comandos. Na paleta de comandos, procure e selecione Azure Functions: Deploy to function app....

  2. Escolha o aplicativo de função que você criou no primeiro artigo. Como você está reimplantando seu projeto no mesmo aplicativo, selecione Implantar para ignorar o aviso sobre a substituição de arquivos.

  3. Após a conclusão da implantação, você pode usar novamente o recurso Executar Função Agora... para acionar a função no Azure.

  4. Verifique novamente os documentos criados em seu contêiner do Azure Cosmos DB para verificar se a associação de saída gera novamente um novo documento JSON.

Clean up resources (Limpar recursos)

No Azure, os recursos referem-se a aplicativos de função, funções, contas de armazenamento e assim por diante. Eles são agrupados em grupos de recursos e você pode excluir tudo em um grupo excluindo o grupo.

Criou recursos para concluir estes guias de introdução. Você pode ser cobrado por esses recursos, dependendo do status da sua conta e do preço do serviço. Se já não precisar dos recursos, pode eliminá-los da seguinte forma:

  1. No Visual Studio Code, pressione F1 para abrir a paleta de comandos. Na paleta de comandos, procure e selecione Azure: Open in portal.

  2. Escolha seu aplicativo de função e pressione Enter. A página do aplicativo de função é aberta no portal do Azure.

  3. Na guia Visão geral, selecione o link nomeado ao lado de Grupo de recursos.

    Captura de ecrã a mostrar a seleção do grupo de recursos a eliminar da página da aplicação de funções.

  4. Na página Grupo de recursos, revise a lista de recursos incluídos e verifique se eles são aqueles que você deseja excluir.

  5. Selecione Eliminar grupo de recursos e siga as instruções.

    A eliminação pode demorar alguns minutos. Quando terminar, é apresentada uma notificação durante alguns segundos. Também pode selecionar o ícone de sino na parte superior da página para ver a notificação.

Próximos passos

Você atualizou sua função acionada HTTP para gravar documentos JSON em um contêiner do Azure Cosmos DB. Agora você pode aprender mais sobre como desenvolver funções usando o Visual Studio Code: