Share via


Conectar o Azure Functions ao Banco de Dados SQL do Azure usando o Visual Studio Code

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

Este artigo mostra como usar o Visual Studio Code para conectar o Banco de Dados SQL do Azure à 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 uma tabela no Banco de Dados SQL do Azure.

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

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

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

Mais detalhes sobre as configurações para associações do SQL do Azure e gatilho para o Azure Functions estão disponíveis na documentação do Azure Functions.

Criar seu banco de dados SQL do Azure

  1. Siga o início rápido de criação do Banco de Dados SQL do Azure para criar um Banco de Dados SQL do Azure sem servidor. O banco de dados pode estar vazio ou ser criado a partir do conjunto de dados de exemplo AdventureWorksLT.

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

    Prompt Seleção
    Grupo de recursos Escolha o grupo de recursos em que o aplicativo de funções foi criado no artigo anterior.
    Nome do banco de dados Insira mySampleDatabase.
    Nome do servidor Insira um nome exclusivo para o seu servidor. Não podemos fornecer um nome do servidor exato a ser usado porque os nomes dos servidores devem ser globalmente exclusivos para todos os servidores no Azure, não apenas para uma assinatura.
    Método de autenticação Selecione Autenticação do SQL Server.
    Logon de administrador do servidor Digite azureuser.
    Senha Insira uma senha que atenda aos requisitos de complexidade.
    Permitir que serviços e recursos do Azure acessem este servidor Selecione Sim na barra superior.
  3. Após a conclusão da criação, navegue até a folha do banco de dados no portal do Azure e, em Configurações, selecione Cadeias de conexão. Copie a cadeia de conexão ADO.NET da autenticação SQL. Cole a cadeia de conexão em um documento temporário para uso posterior.

    Captura de tela da cópia da cadeia de conexão do Banco de Dados SQL do Azure no portal do Azure.

  4. Crie uma tabela para armazenar os dados da solicitação HTTP. No portal do Azure, navegue até a folha do banco de dados e selecione Editor de consultas. Insira a consulta a seguir para criar uma tabela chamada dbo.ToDo:

    CREATE TABLE dbo.ToDo (
        [Id] UNIQUEIDENTIFIER PRIMARY KEY,
        [order] INT NULL,
        [title] NVARCHAR(200) NOT NULL,
        [url] NVARCHAR(200) NOT NULL,
        [completed] BIT NOT NULL
    );
    
  5. Confirme se o Azure Function poderá acessar o Banco de Dados SQL do Azure verificando as configurações de firewall do servidor. Navegue até a folha do servidor no portal do Azure e, em Segurança, selecione Rede. A exceção para Permitir que os serviços e recursos do Azure acessem este servidor deve ser verificada.

    Captura de tela da verificação das configurações de firewall do Banco de Dados SQL do Azure no portal do Azure.

Atualizar as configurações do aplicativo de funções

No artigo anterior do guia de início rápido, um aplicativo de funções foi criado no Azure. Neste artigo, você atualizará seu aplicativo para gravar dados para o Banco de Dados SQL do Azure que você acabou de criar. Para se conectar ao Banco de Dados SQL do Azure, será necessário adicionar a cadeia de conexão dele às configurações do aplicativo. Em seguida, baixe a nova configuração no arquivo local.settings.json para que seja possível se conectar ao Banco de Dados SQL do Azure quando ele estiver em execução localmente.

  1. Edite a cadeia de conexão no documento temporário criado anteriormente. Substitua o valor de Password com a senha usada ao criar o Banco de Dados SQL do Azure. Copie a cadeia de conexão atualizada.

  2. Pressione Ctrl/Cmd+shift+P para abrir a paleta de comandos, depois 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 prompts:

    Prompt Seleção
    Insira o nome da configuração do novo aplicativo Digite SqlConnectionString.
    Insira o valor de “SqlConnectionString" Cole a cadeia de conexão do Banco de Dados SQL do Azure que você acabou de copiar.

    Isso cria uma conexão nomeada da configuração de aplicativo SqlConnectionString no seu aplicativo de funções no Azure. Agora, você pode baixar essa configuração no arquivo local.settings.json.

  4. Pressione Ctrl/Cmd+shift+P novamente para abrir a paleta de comandos, depois 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 da cadeia de conexão. A maioria das configurações baixadas não é usada durante a execução local.

Registrar as extensões de associação

Como você está usando uma associação de saída do SQL do Azure, será necessário obter a extensão das associações correspondentes instaladas antes de executar o projeto.

Com exceção dos gatilhos de timer e HTTP, as associações são implementadas como pacotes de extensão. Execute o comando dotnet add package na janela Terminal para adicionar o pacote de extensão do SQL do Azure ao seu projeto.

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

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, cuja aparência é semelhante à seguinte:

{
  "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
  }
}

:::

Agora é possível adicionar a associação de saída do SQL do Azure ao seu projeto.

Adicionar uma associação de saída

No Functions, cada tipo de associação requer que um direction, type e um name exclusivo seja definido no arquivo functions.json. A maneira como você define esses atributos depende do idioma do seu aplicativo de funções.

Abra o arquivo de projeto HttpExample.cs e adicione a seguinte classe ToDoItem, que define o objeto que é gravado no banco de dados:

namespace AzureSQL.ToDo
{
    public class ToDoItem
    {
        public Guid Id { get; set; }
        public int? order { get; set; }
        public string title { get; set; }
        public string url { get; set; }
        public bool? completed { get; set; }
    }
}

Em um projeto de biblioteca de classes C#, as associações são definidas como atributos de associação no método de função. O arquivo function.json exigido por Functions é gerado automaticamente com base nesses atributos.

Abra o arquivo de projeto HttpExample.cs e adicione a seguinte classe de tipo de saída, que define os objetos combinados que serão gerados de nossa função para a resposta HTTP e a saída SQL:

public static class OutputType
{
    [SqlOutput("dbo.ToDo", connectionStringSetting: "SqlConnectionString")]
    public ToDoItem ToDoItem { get; set; }
    public HttpResponseData HttpResponse { get; set; }
}

Adicione uma instrução using à biblioteca Microsoft.Azure.Functions.Worker.Extensions.Sql na parte superior do arquivo:

using Microsoft.Azure.Functions.Worker.Extensions.Sql;

Os atributos de associação são definidos diretamente em seu código. A configuração de saída do SQL do Azure descreve os campos necessários para executar uma associação de saída do SQL do Azure.

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

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

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

const sendToSql = output.sql({
  commandText: 'dbo.ToDo',
  connectionStringSetting: 'SqlConnectionString',
});

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

@app.generic_output_binding(arg_name="toDoItems", type="sql", CommandText="dbo.ToDo", ConnectionStringSetting="SqlConnectionString"
    data_type=DataType.STRING)

Nesse código, arg_name identifica o parâmetro de associação referenciado em seu código, type indica que a associação de saída é uma associação de saída SQL, CommandText é a tabela na qual a associação grava e ConnectionStringSetting é o nome de uma configuração de aplicativo que contém a cadeia de conexão do SQL do Azure. A cadeia de conexão está na configuração SqlConnectionString no arquivo local.settings.json.

Adicionar o código que usa a associação de saída

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

[Function("HttpExample")]
public static OutputType 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 SQL output binding.
    return new OutputType()
    {
         ToDoItem = new ToDoItem
        {
            id = System.Guid.NewGuid().ToString(),
            title = message,
            completed = false,
            url = ""
        },
        HttpResponse = response
    };
}

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

const data = JSON.stringify([
  {
    // create a random ID
    Id: crypto.randomUUID(),
    title: name,
    completed: false,
    url: '',
  },
]);

// Output to Database
context.extraOutputs.set(sendToSql, data);

Para utilizar o modelo crypto, adicione a seguinte linha à parte superior do arquivo:

const crypto = require("crypto");

Neste ponto, sua função deve ser a seguinte:

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

const sendToSql = output.sql({
  commandText: 'dbo.ToDo',
  connectionStringSetting: 'SqlConnectionString',
});

app.http('HttpExample', {
  methods: ['GET', 'POST'],
  extraOutputs: [sendToSql],
  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' };
      }

      // Stringified array of objects to be inserted into the database
      const data = JSON.stringify([
        {
          // create a random ID
          Id: crypto.randomUUID(),
          title: name,
          completed: false,
          url: '',
        },
      ]);

      // Output to Database
      context.extraOutputs.set(sendToSql, data);

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

Atualize HttpExample\function_app.py para correspondê-lo ao código a seguir. Atualize o parâmetro toDoItems à definição de função e toDoItems.set() abaixo da instrução if name::

import azure.functions as func
import logging
from azure.functions.decorators.core import DataType

app = func.FunctionApp()

@app.function_name(name="HttpTrigger1")
@app.route(route="hello", auth_level=func.AuthLevel.ANONYMOUS)
@app.generic_output_binding(arg_name="toDoItems", type="sql", CommandText="dbo.ToDo", ConnectionStringSetting="SqlConnectionString"
    data_type=DataType.STRING)
def test_function(req: func.HttpRequest, toDoItems: func.Out[func.SqlRow]) -> func.HttpResponse:
     logging.info('Python HTTP 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:
        toDoItems.set(func.SqlRow({"id": uuid.uuid4(), "title": name, "completed": false, url: ""}))
        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
                )

Executar a função localmente

O Visual Studio Code integra-se ao Azure Functions Core Tools para permitir que você execute esse projeto em seu computador de desenvolvimento local antes da publicação no Azure. Se você ainda não tiver o Core Tools instalado localmente, será solicitado que você o instale na primeira vez que executar o projeto.

  1. Para chamar sua função, pressione F5 para iniciar o projeto de aplicativo de funções. O painel Terminal exibirá a saída do Core Tools. Seu aplicativo é iniciado no painel Terminal. Você pode ver o ponto de extremidade de URL de sua função disparada por HTTP localmente.

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

    Se o Core Tools ainda não estiver instalado, selecione Instalar para instalar o Core Tools quando solicitado a fazê-lo.
    Se você tiver problemas com a execução no Windows, verifique se o terminal padrão do Visual Studio Code não está definido como bash WSL.

  2. Com o Core Tools em execução, acesse a área Azure: Funções. Em Funções, expanda Projeto Local>Funções. Clique com o botão direito do mouse (Windows) ou clique em CTRL - (macOS) na função HttpExample e escolha Função Executar Agora... .

    Captura de executar função agora no Visual Studio Code.

  3. Em Insira o corpo da solicitação, pressione ENTER para enviar uma mensagem à 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 o Core Tools e desconectar o depurador.

Executar a função localmente

  1. Como no artigo anterior, clique em F5 para iniciar o projeto do aplicativo de funções e o Core Tools.

  2. Com o Core Tools em execução, acesse a área Azure: Funções. Em Funções, expanda Projeto Local>Funções. Clique com o botão direito do mouse (CTRL-clique no Mac) na função HttpExample e escolha Executar Função Agora... .

    Captura do item de menu Executar função agora no Visual Studio Code.

  3. Em Insira o corpo da solicitação, você verá o valor do corpo da mensagem de solicitação igual a { "name": "Azure" }. Clique em ENTER para enviar essa mensagem de solicitação à função.

  4. Depois que uma resposta for retornada, clique em CTRL + C para interromper o Core Tools.

Verifique se as informações foram gravadas no banco de dados

  1. No portal do Azure, volte para o Banco de Dados SQL do Azure e selecione Editor de consultas.

    Captura de tela de logon no editor de consultas no portal do Azure.

  2. Conecte-se ao banco de dados e expanda o nó Tabelas no pesquisador de objetos à esquerda. Clique com o botão direito do mouse na tabela dbo.ToDo e selecione Selecionar as Primeiras 1000 Linhas.

  3. Verifique se as novas informações foram gravadas no banco de dados pela associação de saída.

Reimplementar e verificar o aplicativo atualizado

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

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

  3. Após a conclusão da implantação, use novamente o recurso Executar Função Agora... para disparar a função no Azure.

  4. Clique mais uma vez em Verificar os dados gravados no Banco de Dados SQL do Azure para verificar se a associação de saída vai gerar um documento JSON novamente.

Limpar os recursos

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

Você criou recursos para concluir esses guias de início rápido. Você pode ser cobrado por esses recursos, dependendo do status de conta e preços do serviço. Caso não precise mais dos recursos, é possível excluí-los desta maneira:

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

  2. Escolha seu aplicativo de funções e pressione ENTER. A página do aplicativo de funções é aberta no portal do Azure.

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

    Captura de tela de seleção do grupo de recursos para excluir da página do aplicativo 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 Excluir grupo de recursos e siga as instruções.

    A exclusão poderá levar alguns minutos. Ao ser concluída, uma notificação será exibida por alguns segundos. Também é possível selecionar o ícone de sino na parte superior da página para exibir a notificação.

Próximas etapas

Você atualizou a função disparada por HTTP para gravar dados no Banco de Dados SQL do Azure. Agora você pode saber mais sobre o desenvolvimento no Functions usando o Visual Studio Code: