Comunicação assíncrona entre microsserviços
As aplicações baseadas no Devprime incorporam nativamente uma aborgaem ‘Event-Driven architecture’ recebendo eventos externos, processam regras de negócio emitindo eventos internos e caso necessário propagam os eventos externamente utilizando o adapter Stream que se conecta nativamente com RabbitMQ, Kafka e outras plataformas.
Nesse momento montaremos uma demonstração envolvendo dois microsserviço. O primeiro é “Order” para receber pedidos e o segundo “Payment” para processar o pagamento. No exemplo utilizaremos dois containers criados no Docker. É fundamental subir os containers MongoDB e RabbitMQ e configurar adicionar a fila “orderevents e paymentevents” no Rabbitmq. Antes de avançar siga os passos iniciais instalando o Devprime CLI.
Se você já possuir ss serviços MongoDB/RabbitMQ altere as configurações no arquivo /src/App/app/appsettings.json no State e no Stream com as suas credenciais.
Criando o primeiro microsserviço “Order”
Nós utilizaremos o Devprime CLI para a criação do microsserviços. Nesse exemplo informaremos o nome da nova aplicação, o tipo de serviço de Stream como “RabbitMQ” para emissão de eventos assíncronos e o State como o “MongoDB” para a persistência dos dados. Para iniciar um novo microsserviço utilize o exemplo de comando apresentado e uma nova aplicação será criada em segundos e pronta para produção.
dp new Order --stream rabbitmq --state mongodb
Adicionando uma regra de negócio do marketplace acelerando o desenvolvimeneto
dp marketplace order
Executando acelerador para implementação de código baseado o Domain. Ao executar o comando a primeira vez nessa demonstração digite “A” para que possa avançar e realizar as alterações.
dp init
O acelerador implementa automaticamente as classes de “Domain Events” em Domain, Event Handlers em Application, “Domain Services” em Application, “Application Services” em Application, persistência em State, “API’s” em Web e alguns testes unitários em Tests como exemplo.
Ao executar a aplicação novamente utilizando o script “.\run.ps1” (Windows) ou “.\run.sh” (Linux/macOS) nós já teremos uma nova visualização da sua API. Abra o browser web na url http://localhost:5000 e localize no Swagger o método post e clique em “Try it out".
Preencha dos dados do JSON para depois clicar em “execute”. Retorne ao prompt de commando acompanhe o resultado no log do microsserviço gerado automaticamente pelo adapter de Observability do Devprime.
Para conferir um exemplo de código implementado pelo acelerador acompanhe o código do OrderCreatedEventHandler.cs na pasta src/Core/Application/EventHandlers/Order que fornece um Handle onde persiste o estado de um aggregate ‘order’ e depois notifica via adapter de Stream.
|
|
Nesse momento o log demonstra o recebimento de um request HTTP na API “Order” que repassa para o serviço de aplicação e depois a regra de negócio no domínio que processa e emite evento “OrderCreated” que além de ter o estado persistido no mongo resultou em uma notificação no mundo externo pelo Stream.
Ao entrar agora no RabbitMQ pelo portal do mesmo é possível observar esse evento na fila “OrderEvents”. Isso significa que esse microsserviço já cumpriu o seu papel e notificou esse fato de negócio para que possa ser percebido por outro serviço.
Como a comunicação nesse exemplo é totalmente assíncrona se houver eventos na fila do RabbitMQ eles serão lidos pelo microsserviço “Payment” assim que configuramos. Você pode parar a aplicação pressionando a tecla “Control” + ”C” a qualquer momento e carregar novamente quando desejar.
Parabéns !!! Você já tem o microsserviço “Order”
Criando o segundo microsserviço “Payment”
O segundo microsserviços chamará “Payment” e iniciaremos a criação do mesmo nesse momento. Um item adicional que faremos durante a implementação é justamente ativar o “subscribe” no adapter de Stream para que possamos receber os eventos emitidos pelo microsserviço “Order”.
Executando o dp new e criando o microsserviços
dp new ms-payment --state mongodb --stream rabbitmq
Adicionando uma regra de negócio do marketplace acelerando o desenvolvimeneto
dp marketplace payment
Executando acelerador para implementação de código baseado o Domain
dp init
Como nós executaremos dois microsserviços no mesmo ambiente local é necessário alterar a porta http do Payment. Na pasta do projeto ms-payment edite o arquivo src/App/appsettings.json na chave web e alterando para 5002 e 5003 conforme exemplo.
|
|
Execute a aplicação utilizando o comando abaixo
.\run.ps1 ou ./run.sh (Linux, MacOS)
Se a aplicação rodou está correndo tudo bem. Feche a mesma com “Control+C” e seguimeremos com as implamentações para habilitar o recebimento dos eventos emitidos pelo microsserviços “Order”.
O próximo passo é adicionar a configuração no serviço de Stream e criação de um DTO para recebermos os dados do evento. Você pode fazer todo o processo manualmente ou utilizando o acelerador abaixo.
dp add subscribe OrderCreated -as PaymentService
Ao confirmar a alteração você terá três arquivos modificados para que possamos avançar nas configurações.
|
|
Abra o arquivo Edite o arquivo OrderCreatedEventDTO.cs e adicione as propriedades abaixo.
code src\Core\Application\Services\Payment\Model\OrderCreatedEventDTO.cs
|
|
Agora edite o arquivo “EventStream.cs” configurando as propriedades definidas no OrderCreatedEventDTO. Nós modificaremos o serviço de aplicação para utilizar o serviço “Add”. Essa implementação indica que estaremos realizando “Subscribe” no evento chamado “OrderCreated” que será vinculado ao alias “Stream1” no adapter Stream.
code src\Adapters\Stream\EventStream.cs
|
|
A etapa final é alterar o arquivo de configuração do Adapter de Stream no arquivo (src/App/appsettings.json) e adicionar o nome da fila / tópico “OrderEvents” em “subscribe” conforme exemplo abaixo.
|
|
Parabéns !!! Você já tem o microsserviços “Payment”
Comunicação assíncrona entre os microsserviços
Agora você cheou ao grande momento de executar os dois microsserviços. Abra cada um em uma janela e execute para quem tenha os serviços ativos. Acesse a url do microsserviços “Order” em http://localhost:5000 e depois vá em Post e clique no botão “Try it out”. Realize um post e acompanhe o resultado incrível com o detalhamento completo em cada microsserviços e o Payment reagindo ao evento recebido.
Nesse momento nós estamos conferindo o resultado do processamento no microsserviços “Order” que recebe
um post e emite o evento “OrderCreated”. Todos os detalhes são gerados automaticamente pelo adapter Observability do Devprime.
[INF][Web]["https://localhost:5001;http://localhost:5000"][Host]["Production"][Parameters]["Appsettings"][RequestId: 3282e6f8-d2bd-4ccf-934a-546276a83038]
[2021-06-19T20:23:07.654-03:00][INF][Web]["HTTP"][Order][Add]["{\n \"customerName\": \"Ramon\",\n \"customerTaxID\": \"string\",\n \"itens\": [\n {\n \"description\": \"string\",\n \"amount\": 0,\n \"sku\": \"string\",\n \"price\": 0\n }\n ],\n \"total\": 0\n}"][Origin:"https://localhost:5001/swagger/index.html"][RequestId: 06721dfc-fd50-4783-8ea7-df201c22599b]
[INF][Application][OrderService][Add][RequestId: 06721dfc-fd50-4783-8ea7-df201c22599b]
[INF][Domain][Order][Add][RequestId: 06721dfc-fd50-4783-8ea7-df201c22599b]
[INF][Domain][Order][Handle][Event]["OrderCreated"][RequestId: 06721dfc-fd50-4783-8ea7-df201c22599b]
[INF][Application][EventHandler]["OrderCreatedEventHandler"][Event]["OrderCreated"][RequestId: 06721dfc-fd50-4783-8ea7-df201c22599b]
[INF][State][Type "MongoDB"][Alias "State1"][OrderRepository][Add][RequestId: 06721dfc-fd50-4783-8ea7-df201c22599b]
[INF][Stream][Type "RabbitMQ"][Alias "Stream1"][Out][Event]["OrderCreated"]["Delivered"]["OrderEvents"]["{\"SagaId\":\"00000000-0000-0000-0000-000000000000\",\"Id\":\"35bc8937-deb8-4e35-a8c4-003171fd6e1b\",\"CorrelationId\":\"06721dfc-fd50-4783-8ea7-df201c22599b\",\"AppId\":\"3282e6f8-d2bd-4ccf-934a-546276a83038\",\"AppName\":\"ms-order\",\"Version\":1,\"Name\":\"OrderCreated\",\"When\":\"2021-06-19T20:23:07.8540357-03:00\",\"Payload\":{\"CustomerName\":\"Ramon\",\"CustomerTaxID\":\"string\",\"Total\":0,\"ID\":\"55a72f16-f4e5-476b-85d9-e86c6e6f390c\"}}"][RequestId: 06721dfc-fd50-4783-8ea7-df201c22599b]
E agora o momento que chega o evento ‘OrderCreated’ no microsserviços “Payment”.
[INF][Web]["https://localhost:5003;http://localhost:5002"][Host]["Production"][Parameters]["Appsettings"][RequestId: 072b12e7-c941-4b4b-9823-cbd6e4425309]
[INF][Stream][Type "RabbitMQ"][Alias "Stream1"][In][Event]["OrderCreated"]["OrderEvents"]["{\"SagaId\":\"00000000-0000-0000-0000-000000000000\",\"Id\":\"35bc8937-deb8-4e35-a8c4-003171fd6e1b\",\"CorrelationId\":\"06721dfc-fd50-4783-8ea7-df201c22599b\",\"AppId\":\"3282e6f8-d2bd-4ccf-934a-546276a83038\",\"AppName\":\"ms-order\",\"Version\":1,\"Name\":\"OrderCreated\",\"When\":\"2021-06-19T20:23:07.8540357-03:00\",\"Payload\":{\"CustomerName\":\"Ramon\",\"CustomerTaxID\":\"string\",\"Total\":0,\"ID\":\"55a72f16-f4e5-476b-85d9-e86c6e6f390c\"}}"][RequestId: 35bc8937-deb8-4e35-a8c4-003171fd6e1b]
[INF][Application][PaymentService][Add][RequestId: 35bc8937-deb8-4e35-a8c4-003171fd6e1b]
[INF][Domain][Payment][Add][RequestId: 35bc8937-deb8-4e35-a8c4-003171fd6e1b]
[INF][Domain][Payment][Handle][Event]["PaymentCreated"][RequestId: 35bc8937-deb8-4e35-a8c4-003171fd6e1b]
[INF][Application][EventHandler]["PaymentCreatedEventHandler"][Event]["PaymentCreated"][RequestId: 35bc8937-deb8-4e35-a8c4-003171fd6e1b]
[INF][State][Type "MongoDB"][Alias "State1"][PaymentRepository][Add][RequestId: 35bc8937-deb8-4e35-a8c4-003171fd6e1b]
Última modificação October 26, 2023 (795e8af6)Parabéns🚀 Você acabou de desenvolver dois microsserviços. Para utilizar o Kafka bastas alterar as configurações do adapter de Stream.