Exercício – gravar dados com associações de saída

Concluído

No exercício anterior, implementamos um cenário para pesquisar favoritos em um banco de dados do Azure Cosmos DB. Configuramos uma associação de entrada para ler dados da nossa coleção de indicadores. Porém, podemos fazer muito mais. Vamos expandir o cenário para incluir a gravação. Considere o seguinte fluxograma:

Diagrama de fluxo de decisão ilustrando o processo de adição de um indicador ao back-end do Azure Cosmos DB e o retorno de uma resposta.

Nesse cenário, recebemos solicitações para adicionar indicadores à nossa coleção. As solicitações passam a chave, ou a ID, desejada, juntamente com a URL do indicador. Como você pode ver no fluxograma, responderemos com um erro se a chave já existir em nosso back-end.

Se a chave que foi passada para nós não for encontrada, adicionaremos o novo indicador ao nosso banco de dados. Podemos pode parar por aqui, mas vamos fazer um pouco mais.

Observou outra etapa no fluxograma? Até o momento, não fizemos muito com os dados que recebemos em termos de processamento. Nós movemos o que recebemos para um banco de dados. No entanto, em uma solução real, provavelmente processaríamos os dados de alguma forma. Podemos fazer todo o processamento na mesma função, mas neste exercício, mostramos um padrão que descarrega o processamento adicional para outro componente ou parte da lógica de negócios.

O que poderia ser um bom exemplo de descarregamento de trabalho em nosso cenário de indicadores? Bem, e se enviássemos o novo indicador a um serviço de geração de código QR? Esse serviço, por sua vez, geraria um código QR para a URL, armazenaria a imagem no Armazenamento de Blobs e adicionaria o endereço da imagem de QR à entrada na coleção de indicadores. Chamar um serviço para gerar uma imagem QR é demorado. Portanto, em vez de aguardar o resultado, entregamos a tarefa a uma função e permitimos que ela conclua essa tarefa de forma assíncrona.

Assim como o Azure Functions dá suporte a associações de entrada para diferentes fontes de integração, ele também tem um conjunto de modelos para associações de saída para facilitar a gravação de dados em fontes de dados. As associações de saída também são configuradas no arquivo function.json. Como você vê neste exercício, podemos configurar nossa função para trabalhar com várias fontes de dados e serviços.

Importante

Este exercício se baseia nos recursos da área restrita e nos recursos que você criou nas unidades anteriores, especificamente, o banco de dados do Azure Cosmos DB, os indicadores e as associações de entrada. Se você ainda não concluiu os exercícios das unidades anteriores, não poderá realizar este exercício.

Criar uma função disparada por HTTP

  1. No portal do Azure, acesse o aplicativo de funções que você criou selecionando o nome do aplicativo de funções no caminho da trilha na parte superior da página da função HttpTrigger2.

  2. Na guia Funções da página Visão Geral, você deve ter as funções de gatilho HTTP que criou.

  3. Selecione Criar na guia Funções. O painel Criar função será exibido.

  4. Na seção Selecionar um modelo, escolha Gatilho HTTP e selecione Próximo. Aceite os padrões na guia Detalhes do modelo e selecione Criar. O painel Visão geral da Função HttpTrigger3 é exibido.

Adicionar uma associação de entrada do Azure Cosmos DB

Vamos adicionar outra associação de entrada do Azure Cosmos DB.

  1. No menu da Função HttpTrigger3, selecione Integração. O painel Integração é exibido.

  2. Na caixa Gatilho e entradas, selecione Adicionar entrada. O painel Criar Entrada será exibido.

  3. Na lista suspensa Tipo de Associação, selecione Azure Cosmos DB.

  4. A configuração de conexão da conta do Cosmos DB deve ser pré-preenchida com a conexão que você criou no exercício anterior.

    Se você não vir sua conexão listada, siga estas etapas para criar uma nova conexão.

    1. Na seção Detalhes do Azure Cosmos DB, na configuração Conexão da conta do Cosmos DB, selecione o link Nova.

    2. Quando a caixa de diálogo conexão do Cosmos DB for exibida, selecione OK para criar a conexão. Uma nova conexão de conta do Cosmos DB é criada.

  5. Insira os valores a seguir para as outras configurações desse painel. Se quiser saber mais sobre a finalidade de cada configuração, selecione o ícone de informações à direita.

    Configuração Valor Descrição
    Nome do parâmetro do documento bookmark O nome usado para identificar essa associação no código.
    Nome do banco de dados func-io-learn-db O banco de dados com o qual trabalhar. Esse valor é o nome do banco de dados que definimos anteriormente nesta lição.
    Nome da coleção Bookmarks O nome da coleção da qual os dados são lidos. Definimos essa configuração anteriormente na lição.
    ID do documento {id} Adicione {id} para usar a expressão de associação correta e aceite o parâmetro que é transmitido na cadeia de consulta.
    Chave de partição {id} Novamente, adicione {id} para usar a expressão de associação correta e aceite o parâmetro que é transmitido na cadeia de consulta.
    Consulta SQL (opcional) Deixar em branco Estamos recuperando apenas um item de cada vez com base na ID. Portanto, a filtragem com a configuração Documento é melhor do que o uso de uma Consulta SQL nesta instância. Podemos criar uma Consulta SQL para retornar uma entrada (SELECT * from b where b.ID = /id). De fato, essa consulta retornaria um item, mas em uma coleção de itens. Nosso código precisaria manipular uma coleção desnecessariamente. Use a abordagem de Consulta SQL quando deseja obter vários documentos.

    Assim como a associação de entrada que criamos no exercício anterior, queremos procurar um indicador com uma ID específica. Portanto, vinculamos a ID do Documento que a função recebe na cadeia de consulta à associação, conhecida como a expressão de associação. O gatilho de função é uma solicitação HTTP que usa uma cadeia de caracteres de consulta para especificar a ID a ser pesquisada. A associação retorna 0 documentos (não encontrado) ou 1 (encontrado).

  6. Selecione Adicionar para salvar a configuração da ligação de entrada.

Agora, temos uma associação de entrada do Azure Cosmos DB. Vamos adicionar uma associação de saída para gravarmos novas entradas em nossa coleção.

Adicionar uma associação de saída do Azure Cosmos DB

  1. No painel Integração da HttpTrigger3, na caixa Saídas, selecione Adicionar saída. O painel Criar Saída será exibido.

  2. Na lista suspensa Tipo de Associação, selecione Azure Cosmos DB.

  3. A configuração de conexão da conta do Cosmos DB deve ser pré-preenchida com a conexão que você criou anteriormente. Caso contrário, expanda a lista suspensa e selecione a conexão que você definiu para associação de entrada da HttpTrigger3.

  4. Insira os valores a seguir para as configurações restantes da associação de saída.

    Configuração Valor Descrição
    Nome do parâmetro do documento newbookmark O nome usado para identificar essa associação no código. Esse parâmetro é usado para gravar uma nova entrada de indicador.
    Nome do banco de dados func-io-learn-db O banco de dados com o qual trabalhar. Esse valor é o nome do banco de dados que definimos anteriormente nesta lição.
    Nome da coleção Bookmarks O nome da coleção da qual os dados são lidos. Esse valor é o nome do contêiner que definimos anteriormente na lição.
    Chave de partição /id Adicione a chave de partição que definimos quando criamos o contêiner Indicadores do Azure Cosmos DB anteriormente. A chave inserida aqui (especificada na configuração da associação de entrada <key>) precisa corresponder àquela que está no contêiner.
  5. Selecione Adicionar para salvar essa configuração de vinculação de saída.

Agora, temos uma associação para ler na nossa coleção e uma associação para gravar nela.

Adicionar uma associação de saída do Armazenamento de Filas do Azure

O Armazenamento de Filas do Azure é um serviço para armazenamento de mensagens que podem ser acessadas de qualquer lugar do mundo. O tamanho de uma única mensagem pode ser de até 64 KB e uma fila pode conter milhões de mensagens, até a capacidade total da conta de armazenamento em que ela está definida. O diagrama a seguir mostra, de maneira geral, como uma fila é usada em nosso cenário.

Ilustração mostrando uma fila de armazenamento com uma função efetuando push e outra função removendo mensagens.

Neste exemplo você pode ver que uma função chamada add-bookmark adiciona mensagens a uma fila e outra chamada gen-qr-code remove mensagens da mesma fila e processa a solicitação. Como gravamos mensagens ou as enviamos por push à fila de add-bookmark, adicionamos uma nova associação de saída à sua solução.

Vamos criar a associação por meio do portal.

  1. No painel Integração da sua função, na caixa Saídas, selecione Adicionar saída. O painel Criar Saída será exibido.

  2. Na lista suspensa Tipo de Associação, selecione Armazenamento de Filas do Azure.

    Se uma mensagem for exibida solicitando que você instale a extensão Microsoft.Azure.WebJobs.Extensions.Storage, selecione instalar e aguarde a conclusão.

Em seguida, configuramos uma conexão de conta de armazenamento, em que nossa fila está hospedada.

  1. No campo Conexão da conta de armazenamento, selecione Novo. A caixa de diálogo Nova conexão da Conta de Armazenamento será exibida.

  2. No início deste módulo, quando você criou seu aplicativo de funções, uma conta de armazenamento também foi criada para você. Selecione-o na lista suspensa e selecione OK.

    A configuração Conexão de conta de armazenamento é preenchida com o nome de uma conexão.

Embora possamos manter os valores padrão, vamos alterar algumas configurações para dar mais significado às propriedades restantes.

  1. Preencha as configurações no painel Criar Saída, substituindo os valores antigos a seguir pelos novos valores:

    Configuração Valor antigo Novo valor Descrição
    Nome do parâmetro de mensagem outputQueueItem newmessage A propriedade de associação que usamos no código.
    Nome da fila outqueue bookmarks-post-process O nome da fila em que estamos colocando indicadores para que outra função possa processá-los ainda mais.
  2. Selecione Adicionar para salvar a configuração de saída do Armazenamento de Filas do Azure.

Atualizar implementação da função

Agora temos todas as vinculações configuradas. É hora de usá-las em nossa função.

  1. Para abrir o arquivo index.js no editor de códigos, selecione a função HttpTrigger3.

  2. No menu, selecione Código + Teste. O painel Código + Teste é exibido para sua função.

  3. Substitua todo o código em index.js pelo código do snippet a seguir e, na barra de comandos, selecione Salvar.

    module.exports = function (context, req) {
    
        var bookmark = context.bindings.bookmark;
        if(bookmark){
                context.res = {
                status: 422,
                body : "Bookmark already exists.",
                headers: {
                'Content-Type': 'application/json'
                }
            };
        }
        else {
            
            // Create a JSON string of our bookmark.
            var bookmarkString = JSON.stringify({ 
                id: req.body.id,
                url: req.body.url
            });
    
            // Write this bookmark to our database.
            context.bindings.newbookmark = bookmarkString;
    
            // Push this bookmark onto our queue for further processing.
            context.bindings.newmessage = bookmarkString;
    
            // Tell the user all is well.
            context.res = {
                status: 200,
                body : "bookmark added!",
                headers: {
                'Content-Type': 'application/json'
                }
            };
        }
        context.done();
    };
    

Vamos detalhar o que esse código faz:

  • Como essa função altera os dados, esperamos que a solicitação HTTP seja POST e que os dados do indicador façam parte do corpo da solicitação.
  • Nossa associação de entrada do Azure Cosmos DB tenta recuperar um documento, ou indicador, usando a id que recebemos. Se ela encontrar uma entrada, o objeto bookmark será definido. A condição if(bookmark) verifica se uma entrada foi encontrada.
  • Para adicionar ao banco de dados, basta definir o parâmetro de associação context.bindings.newbookmark para a nova entrada de indicador, que criamos como uma cadeia de caracteres JSON.
  • Para postar uma mensagem na fila, basta definir o parâmetro context.bindings.newmessage.

Observação

A única tarefa que você realizou foi criar uma associação de fila. Não foi necessário criar a fila explicitamente. Você está testemunhando o poder das associações! Como declarado na notificação a seguir, a fila será criada automaticamente caso ainda não exista.

Captura de tela mostrando a mensagem de que a fila será criada automaticamente. .

  1. Selecione function.json na lista suspensa no caminho e faça as seguintes alterações:<functionapp> \ HttpTrigger3 \.

    1. "collectionName"Altere todas as instâncias de para "containerName".
    2. "connectionStringSetting"Altere todas as instâncias de para "connection".
    3. Exclua as referências para "methods": [].
  2. Seu arquivo de function.json final deve ser semelhante a esse código.

    {
      "bindings": [
        {
          "authLevel": "function",
          "type": "httpTrigger",
          "direction": "in",
          "name": "req",
          "methods": [
            "get",
            "post"
          ]
        },
        {
          "type": "http",
          "direction": "out",
          "name": "res"
        },
        {
          "name": "bookmark",
          "direction": "in",
          "type": "cosmosDB",
          "partitionKey": "{id}",
          "databaseName": "func-io-learn-db",
          "containerName": "Bookmarks",
          "connection": "your-database_DOCUMENTDB",
          "id": "{id}"
        },
        {
          "name": "newbookmark",
          "direction": "out",
          "type": "cosmosDB",
          "partitionKey": "/id",
          "databaseName": "func-io-learn-db",
          "containerName": "Bookmarks",
          "connection": "your-database_DOCUMENTDB"
        },
        {
          "name": "newmessage",
          "direction": "out",
          "type": "queue",
          "queueName": "bookmarks-post-process",
          "connection": "your-storage-account_STORAGE"
        }
      ]
    }
    
  3. Na barra de comandos, selecione Salvar.

Então, é isso. Vamos ver nosso trabalho em ação na próxima seção.

  1. Para abrir o arquivo run.ps1 no editor de códigos, selecione a função HttpTrigger3 na barra de navegação na parte superior do painel.

  2. No menu Função, em Desenvolvedor, selecione Código + Teste. O painel Codificar + Testar da função HttpTrigger3 é exibido, mostrando o conteúdo padrão do run.ps1.

  3. Substitua o conteúdo do arquivo pelo código a seguir.

    using namespace System.Net
    
    param($Request, $bookmark, $TriggerMetadata)
    
    if ($bookmark) {
        $status = 422
        $body = "Bookmark already exists."
    }
    else {
        $newBookmark = @{ id = $Request.Body.id; url = $Request.Body.url }
    
        Push-OutputBinding -Name newbookmark -Value $newBookmark
    
        Push-OutputBinding -Name newmessage -Value $newBookmark
    
        $status = [HttpStatusCode]::OK
        $body = "bookmark added!"
    }
    
    Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{
        StatusCode = $status
        Body = $body
        ContentType = "application/json"
    })
    
  4. Selecione Salvar na barra de comandos. Uma conexão será feita, e uma sessão do arquivo de log será aberta.

Vamos detalhar o que esse código faz:

  • Como essa função altera os dados, esperamos que a solicitação HTTP seja POST e que os dados do indicador façam parte do corpo da solicitação.
  • Nossa associação de entrada do Azure Cosmos DB tenta recuperar um documento, ou indicador, usando a id da solicitação. Se ela encontrar uma entrada, o objeto bookmark será definido. A condição if ($bookmark) verifica se uma entrada foi encontrada.
  • Adicionar ao banco de dados é tão simples quanto chamar Push-OutputBinding com o nome da associação de saída do Azure Cosmos DB (newbookmark) e o valor do objeto $newBookmark.
  • Postar uma mensagem em nossa fila é tão simples quanto chamar Push-OutputBinding com o nome da associação de saída da fila (newmessage) e o valor do objeto $newBookmark.

Observação

A única tarefa que você realizou foi criar uma associação de fila. Não foi necessário criar a fila explicitamente. Você está testemunhando o poder das associações! Como declarado na notificação a seguir, a fila será criada automaticamente caso ainda não exista.

Captura de tela mostrando a dica de ferramenta da interface do usuário informando que a fila será criada automaticamente.

Então, é isso. Vamos ver nosso trabalho em ação na próxima seção.

Experimente

Agora que há várias associações de saída, os testes ficam um pouco mais complicados. Nas unidades anteriores, estávamos contentes em testar enviando uma solicitação HTTP com uma cadeia de caracteres de consulta, mas queremos executar uma postagem HTTP desta vez. Também precisamos verificar se as mensagens estão chegando à uma fila.

  1. Na barra de comandos do painel Código + Teste para sua função HttpTrigger3, selecione Testar/Executar. Um novo painel é exibido, com a guia Entrada aberta, conforme mostrado nesta imagem:

    Captura de tela mostrando o painel testar/executar.

  2. Na lista suspensa Método HTTP, verifique se POST está selecionado.

  3. Substitua o conteúdo do Corpo da solicitação pelo seguinte objeto JSON:

    {
        "id": "docs",
        "url": "https://learn.microsoft.com/azure"
    }
    
  4. Selecione Executar.

  5. O progresso programático é mostrado no painel Logs. Quando concluído, verifique se a guia Saída exibe "O indicador já existe", na configuração de conteúdo de resposta HTTP.

    Captura de tela da guia Saída que mostra a resposta

    Você adicionou o item de indicador no Exercício – Ler dados com associações de entrada. A resposta confirma que o JavaScript var bookmark = context.bindings.bookmark está funcionando corretamente e que o código do PowerShell está fazendo a mesma conexão.

  6. Vamos postar um segundo indicador no banco de dados. Selecione a guia Entrada.

  7. Substitua o conteúdo do Corpo da solicitação pelo seguinte objeto JSON:

    {
        "id": "github",
        "url": "https://www.github.com"
    }
    
  8. Selecione Executar.

  9. Verifique se a guia Saída exibe "indicador adicionado!" no conteúdo da resposta HTTP, conforme mostra a captura de tela a seguir.

    Captura de tela da guia saída mostrando a resposta da adição do favorito.

Parabéns! Sua função funciona como projetado! Mas, e quanto à operação de fila que adicionamos ao código? Bem, vamos ver se algo foi gravado em uma fila.

Verificar se uma mensagem foi gravada na fila

As filas do Armazenamento de Filas do Azure são hospedadas em uma conta de armazenamento. Você configurou a conta de armazenamento quando criou a associação de saída.

  1. Na barra de pesquisa global do portal do Azure, insira contas de armazenamento e, na lista de resultados, selecione Contas de armazenamento. O painel Contas de armazenamento é exibido.

    Captura de tela mostrando os resultados da pesquisa para a pesquisa Conta de Armazenamento.

  2. Selecione a conta de armazenamento que você usou para configurar a associação de saída newmessage.

  3. No menu da Conta de armazenamento, em Armazenamento de dados, selecione Filas para listar as filas hospedadas por essa conta de armazenamento. Verifique se a fila bookmarks-post-process está listada, conforme mostrado na captura de tela a seguir.

    Captura de tela mostrando filas hospedadas por essa conta de armazenamento.

  4. Selecione bookmarks-post-process para listar as mensagens que estão na fila. Se tudo saiu conforme o planejado, a fila inclui a mensagem que você postou quando adicionou um indicador no banco de dados. Ele deverá ter a seguinte aparência.

    Captura de tela da fila de mensagens com duas mensagens.

    Neste exemplo, a mensagem recebeu uma ID exclusiva e que o campo Texto da mensagem exibe seu indicador no formato JSON. Não há nenhuma mensagem para o indicador docs do Azure que você tentou adicionar porque ela já existia no banco de dados.

  5. Você pode continuar testando a função alterando o corpo da solicitação no painel de teste com novos conjuntos de IDs/URLs e executando a função. Observe essa fila para ver mais mensagens chegarem. Você também pode examinar o banco de dados para verificar se novas entradas foram adicionadas.

Neste exercício, expandimos nosso conhecimento sobre associações para associações de saída gravando dados no Azure Cosmos DB. Adicionamos uma associação de saída para postar mensagens em uma fila do Azure. Este exemplo demonstra o verdadeiro poder das associações para ajudar você a moldar e mover dados de fontes de entrada para vários destinos. Não foi necessário escrever nenhum código de banco de dados nem gerenciar cadeias de conexão. Nesse caso, configuramos associações de maneira declarativa e permitimos que a plataforma cuidasse da proteção das conexões e do dimensionamento da função e das conexões.