Utilizando o Azure Service Bus com Node.js
Tags: azure, node, beginners, tutorial
Published: 2019-10-12 14:52:03

O [Azure Service Bus](https://azure.microsoft.com/pt-br/services/service-bus/?WT.mc_id=msplatam-devto-cxa) é um sistema de mensagem como serviço (MaaS) que proporciona o desacoplamento de aplicações por meio da distribuição de mensagens entre sistemas. Esse desacoplamento permite a criação de soluções altamente escalonáveis.

Mas antes da implementação, iremos entender como o serviço funciona e os conceitos envolvidos.

## Conceitos

**O que é uma mensagem?**

Uma mensagem é um tipo de dados que serve para a comunicação entre os sistemas. Essa mensagem pode ser um simples JSON como também um arquivo de imagem ou apenas texto. Uma mensagem é dividida em **Payload** e em **Label**.

- Payload: O payload é o corpo da mensagem onde estão localizados os dados que serão transmitidos.
- Label: O label serve para informar quem receberá a mensagem.

**O que é uma fila?**

A fila é o local onde as mensagens ficam armazenadas após serem enviadas pelo remetente e também é o local onde o receptor irá receber mensagens para então processá-las.

![](https://i.postimg.cc/CLPG9G1v/about-service-bus-queue.png)

**O que são os tópicos?**

Os tópicos também são utilizados para enviar e receber mensagens. Enquanto a fila é usado apenas para comunicação ponta-a-ponta, os tópicos são utilizados para cenários onde hajam múltiplos receptores. Um receptor inscrito em um tópico recebe uma cópia de cada mensagem presente naquele tópico.

![](https://i.postimg.cc/htXLnXQK/about-service-bus-topic.png)

## Demonstração
Com esses conceitos em mente, estaremos prontos para iniciar um pequeno projeto simulando o clássico produtor/consumidor. Para esse exemplo iremos utilizar as seguintes ferramentas:

 - [Visual Studio Code](http://code.visualstudio.com/?WT.mc_id=msplatam-devto-cxa)
 - [Node.js](https://nodejs.org/en/)
 - [Conta no Microsoft Azure](https://azure.microsoft.com/en-us/free/?WT.mc_id=msplatam-devto-cxa)

Para os universitários de plantão: o Azure disponibiliza um crédito de U$100,00 para você utilizar os serviços sem precisar cadastrar um cartão de crédito. Ative seu benefício [aqui](https://azure.microsoft.com/pt-br/free/students/?WT.mc_id=msplatam-devto-cxa)!

### Criando o Service Bus no Azure

O processo de criação do recurso [Service Bus](https://azure.microsoft.com/pt-br/services/service-bus/?WT.mc_id=msplatam-devto-cxa) é muito simples. É necessário realizar o login e acessar o painel do Azure. Você pode criar o recurso através do menu localizado a esquerda ou pesquisando por [Service Bus](https://azure.microsoft.com/pt-br/services/service-bus/?WT.mc_id=msplatam-devto-cxa) na barra de pesquisa, como mostrado abaixo:

![](https://i.postimg.cc/RhPt5mM3/Capturar.png)

Durante a criação do recurso, serão solicitadas algumas informações. Preencha semelhante a imagem abaixo, clique em **Create** e aguarde a finalização do processo de criação.

![](https://i.postimg.cc/h4MT7L9S/Capturar2.png)

Após finalizado o processo de criação, devemos salvar a string de conexão gerada. É através dessa string que nossa aplicação se comunicará com o Azure e enviará/receberá as mensagens. Para isso, entre no recurso Service Bus criado e através do menu de navegação esquerdo, em **Settings**, procure por **Shared access policies**.

![](https://i.postimg.cc/wvpLDFfB/Capturar-3.png)

Clique em **RootManageSharedAccessKey**

![](https://i.postimg.cc/W1xM1s0g/Capturar-4.png)

Em seguida, anote a string de conexão mostrada em **Primary Connection String**

![](https://i.postimg.cc/k4v8s8zv/Capturar-5.png)

Certo, agora precisamos criar uma fila para armazenar as mensagens em nosso Service Bus. Para isso, vá até **Overview** e clique em **Queue**. Será exibido um formulário para configurarmos nossa fila. Veja a imagem abaixo como exemplo e após preenchido clique em **Create**.

![](https://i.postimg.cc/rsy4PsLX/Capturar-6.png)

Após finalizado, estaremos prontos para desenvolver nossa aplicação de exemplo.

### Mão na massa
Abra seu [Visual Studio Code](http://code.visualstudio.com/?WT.mc_id=msplatam-devto-cxa) e no terminal crie um novo projeto Node.js através do comando:

    npm init -y
Esse comando irá criar um arquivo package.json padrão. Abra o package.json e substitua pelo código abaixo:

    {
	    "name":  "azure-service-bus",
	    "version":  "1.0.0",
	    "description":  "Exemplo de funcionamento do Azure Service Bus",
	    "main":  "src/factory.js",
	    "scripts": {
		    "factory":  "node src/factory.js",
		    "consumer":  "node src/consumer.js"
		},
		"repository": {
			"type":  "git",
			"url":  "https://github.com/jrafaelsantana/azure-servicebus-exemplo.git"
		},
		"author":  "Rafael Santana",
		"license":  "MIT"
	}
### Organizando o projeto
Crie os diretórios e arquivos conforme a imagem abaixo:

![](https://i.postimg.cc/5tv8HDmG/Capturar-7.png)

### Instalando as dependências
Para esse exemplo precisamos instalar dois pacotes. São eles:

 - @azure/service-bus
 - config

O @azure/service-bus é uma biblioteca para criar clientes do [Azure Service Bus](https://azure.microsoft.com/pt-br/services/service-bus/?WT.mc_id=msplatam-devto-cxa) em Node.js. Para instalar, execute o comando:

    npm install @azure/service-bus

O config é um pacote para definirmos parâmetros de ambiente. Usaremos esse pacote para manter nosso código organizado e limpo. Instale o config através do comando:

    npm install config

### Configurações da conexão
Abra o arquivo **config/default.json** e preencha seguindo o modelo abaixo:

    {
		"Azure": {
			"serviceBus": {
				"queueName": "NOME DE SUA FILA",
				"connectionString": "SUA STRING DE CONEXÃO"
			}
		}
	}

Todas nossas variáveis de ambiente serão armazenadas nesse arquivo, facilitando a manutenção do código.

### Criação do produtor de mensagens

Abra o arquivo **src/factory.js** e inclua o código abaixo. O código está com comentários explicando trechos importantes.

    const config = require('config');
    const { ServiceBusClient } = require("@azure/service-bus");
    
    async function main() {
	    //Cria a conexão com o Service Bus utilizando as configurações em config/default.json
	    const cliente = ServiceBusClient.createFromConnectionString(config.get('Azure.serviceBus.connectionString'));
	    const fila = cliente.createQueueClient(config.get('Azure.serviceBus.queueName'));
	    const sender = fila.createSender();

	    try {
	        //Fabricamos 20 mensagens
	        for (let i = 0; i < 20; i++) {
	            //Esse será o conteúdo das nossas mensagens
	            const message = {
	                body: 'Mensagem ' + i,
	                label: 'testes',
	                properties: {
	                    country: 'Brazil',
	                    state: 'PE'
	                }
	            };
	            await sender.send(message); //Envia mensagem
	            console.log('Enviou a mensagem ' + i)
	        }

	        await fila.close(); //Finaliza o cliente da fila
	    } finally {
	        await cliente.close(); //Finaliza o cliente do Service Bus
	    }
	}
	
	main().catch((err) => {
	    console.log(err);
	});

### Criação do consumidor de mensagens

Abra o arquivo **src/consumer.js** e insira o código abaixo. Semelhante ao **factory.js**, o código está com comentários explicando seu funcionamento.

    const config = require('config');
    const { ServiceBusClient, ReceiveMode } = require("@azure/service-bus");
    
    async function main() {
	    //Cria a conexão com o Service Bus utilizando as configurações em config/default.json
	    const cliente = ServiceBusClient.createFromConnectionString(config.get('Azure.serviceBus.connectionString'));
	    const fila = cliente.createQueueClient(config.get('Azure.serviceBus.queueName'));
	    const receiver = fila.createReceiver(ReceiveMode.ReceiveAndDelete); //Cria um receptor no modo ReceiveAndDelete
	    
	    try {
	        //Cria um loop que aguarda novas mensagens serem inseridas na fila para consumi-las
	        for await (let message of receiver.getMessageIterator()) {
	            if (typeof message != 'undefined') {
	                console.log('Mensagem recebida: ' + message.body);
	                await message.complete(); //Informa que a mensagem foi lida
	            }
	        }
	        await fila.close(); //Finaliza o cliente da fila
	    } finally {
	        await cliente.close(); //Finaliza o cliente do Service Bus
	    }
	}
	
	main().catch((err) => {
	    console.log("Error occurred: ", err);
	});

Pronto, nosso produtor e consumidor já estão concluídos. Vamos executar nosso projeto de exemplo para verificar se está funcionando corretamente. Primeiramente, vamos testar nosso **factory.js**. Para isso, vá até o terminal e execute o comando:

    npm run factory

![](https://i.postimg.cc/MKTR0nD1/Capturar-8.png)

Se for mostrado algo semelhante a imagem acima, o seu **factory.js** está funcionando. Agora, vamos testar nosso **consumer.js** utilizando o comando:

    npm run consumer

![](https://i.postimg.cc/Gh5DXb7V/Capturar-9.png)

Tudo certo! As mensagens foram consumidas da nossa fila. Note que nosso **consumer.js** continua em execução mesmo após ter consumido todas as mensagens da fila. Isso acontece pois nosso consumidor foi construído para sempre verificar a existência de novas mensagens. Experimente executar novamente o **consumer.js** enquanto o **factory.js** está aguardando as mensagens.

![](https://thepracticaldev.s3.amazonaws.com/i/75gmx58gjg7vwr5u3hso.gif)

Você também pode receber um conjunto de mensagem de uma única vez utilizando o método **receiveMessages** como o exemplo abaixo:

    //Consume um conjunto de 10 mensagens de uma única vez
    const messages = await receiver.receiveMessages(10);
    console.log(messages.length + ' mensagens recebidas:');
    
    for await (let message of messages) {
	    console.log(message.body);
	    await message.complete();
    }
![](https://thepracticaldev.s3.amazonaws.com/i/1jrofwojutbt5epkixvo.gif)

### Conclusão

Interessante, não é? O [Azure Service Bus](https://azure.microsoft.com/pt-br/services/service-bus/?WT.mc_id=msplatam-devto-cxa) é uma ferramenta indispensável para sua aplicação se tornar altamente escalável. A biblioteca do Service Bus não está disponível apenas para o Node.js mas também para .NET, Java, Python, PHP e Ruby.

Se quiser saber mais sobre as funcionalidades do Azure Service Bus visite a [documentação oficial](https://docs.microsoft.com/pt-br/azure/service-bus-messaging/?WT.mc_id=msplatam-devto-cxa). A documentação é bastante completa e contém vários exemplos de código.

Todo o código está disponibilizado [nesse repositório](https://github.com/jrafaelsantana/azure-servicebus-exemplo).

Até a próxima!

=D