Event Driven Architecture Lab: antes do primeiro evento, as primeiras mudanças#

Um laboratório de arquitetura, uma troca de stack e a decisão de aprender construindo.

Publicado em 19 de outubro de 2026 · Diário de desenvolvimento

Às vezes, começamos um projeto para estudar uma tecnologia e descobrimos que o aprendizado começa muito antes de escrever a primeira linha de código de negócio.

Foi o que aconteceu com o Event Driven Architecture Lab.

A proposta inicial era construir um sistema simplificado de processamento de pedidos usando NestJS, TypeScript, Apache Kafka e PostgreSQL. A ideia era experimentar arquitetura orientada a eventos na prática, começando por um fluxo síncrono e introduzindo mensageria somente depois de estabelecer uma referência para comparação.

O projeto começou a tomar forma em 15 de outubro. Quatro dias depois, a stack já havia mudado, a organização do repositório estava sendo revista e algumas decisões arquiteturais que pareciam simples se transformaram em questões interessantes para investigar.

Nenhum pedido foi processado ainda. Mas já temos algumas coisas para contar.

A ideia original: aprender EDA construindo#

O objetivo do laboratório nunca foi produzir mais um sistema de pedidos com uma arquitetura sofisticada. A intenção é entender o que muda quando substituímos comunicação síncrona por comunicação assíncrona e quais custos essa decisão introduz.

O cenário inicial é relativamente simples:

  • Uma API recebe pedidos.
  • O sistema persiste o pedido e seus itens.
  • Um consumidor simula a reserva de estoque.
  • Outro consumidor simula o envio de uma confirmação.

Na etapa posterior, esses componentes reagirão a eventos publicados no Kafka.

A expectativa é investigar questões como entrega de mensagens, processamento duplicado, idempotência, falhas, retentativas e consistência entre a persistência dos dados e a publicação de eventos.

Mas existe uma premissa importante: antes de introduzir Kafka, precisamos implementar o fluxo síncrono.

Sem uma referência inicial, corremos o risco de atribuir à arquitetura orientada a eventos benefícios ou problemas que não medimos. O laboratório precisa permitir comparações, não apenas demonstrar que conseguimos colocar um broker no meio da comunicação.

A primeira mudança: de NestJS para Symfony#

O repositório nasceu com NestJS e TypeScript. A infraestrutura inicial foi organizada com Docker Compose, PostgreSQL, Kafka e Sqitch para gerenciar as migrações do banco de dados.

A escolha parecia coerente com a proposta. Entretanto, durante a organização do ambiente, decidi mudar a aplicação para PHP e Symfony.

Não foi uma descoberta de que Symfony seria tecnicamente superior ao NestJS. A mudança reflete a direção que quero explorar neste laboratório e a oportunidade de trabalhar com uma stack na qual também posso aprofundar questões de arquitetura.

Em 19 de outubro, o scaffold do NestJS foi removido, o esqueleto mínimo do Symfony foi introduzido e a infraestrutura de execução foi adaptada.

A mudança envolveu o runtime PHP, o Composer, o servidor Apache e os caminhos utilizados pelo ambiente Docker. PostgreSQL, Kafka, Sqitch e Traefik foram preservados.

O resultado foi uma aplicação Symfony funcional, ainda sem endpoints ou regras de negócio.

E isso nos levou à próxima questão.

O framework precisa ser dono da aplicação?#

Quero investigar na prática uma ideia bastante conhecida na Clean Architecture: as regras de negócio não deveriam depender do framework utilizado para expô-las ou executá-las.

Em vez de organizar todo o código dentro da estrutura convencional de um projeto Symfony, decidi experimentar uma separação física mais explícita.

A estrutura atual segue esta direção:

eda-lab/
├── symfony/
│   ├── bin/
│   ├── config/
│   ├── public/
│   ├── var/
│   ├── composer.json
│   └── ...
├── src/
├── db/
├── compose.yml
├── Dockerfile
└── Makefile

O diretório symfony/ concentra a aplicação de entrada, a configuração específica do framework e suas dependências gerenciadas pelo Composer.

O src/ da raiz fica reservado ao código independente do framework.

Essa organização é uma escolha experimental, não uma afirmação de que projetos Clean Architecture precisam seguir exatamente essa estrutura. É perfeitamente possível separar responsabilidades por namespaces e módulos dentro de um único diretório src/.

A pergunta que quero investigar é outra: tornar a fronteira física mais explícita ajuda a reduzir o acoplamento e facilita a substituição futura do framework?

Para sustentar essa separação, não basta mover arquivos. Precisaremos manter as dependências na direção correta, definir contratos úteis e evitar que as regras de negócio importem classes específicas do Symfony.

A estrutura, sozinha, não garante nada disso.

O banco de dados já começou a ganhar forma#

Enquanto a aplicação ainda não possui seu primeiro caso de uso, o banco já tem um esquema inicial para representar clientes, produtos, pedidos, itens e pagamentos.

As migrações são gerenciadas pelo Sqitch, e o ambiente PostgreSQL está funcionando.

Essa parte também merece atenção: o modelo de dados não é um detalhe que desaparecerá quando introduzirmos Kafka. Precisaremos entender como as transações do banco interagem com a publicação de eventos e quais problemas surgem quando essas duas operações não são atômicas.

Ainda não implementamos essa integração. Por enquanto, temos uma base inicial de persistência, não uma solução completa de processamento de pedidos.

Essa distinção importa porque o laboratório deve registrar o estado real do projeto, inclusive aquilo que ainda falta.

E os agentes de IA?#

O uso de agentes de IA também faz parte dos meus objetivos de aprendizado, mas não quero começar delegando a implementação inteira e recebendo um resultado que não consigo explicar.

Neste momento, o Codex está sendo utilizado para tarefas operacionais, como reorganizar a estrutura do repositório e ajustar a configuração da infraestrutura. As decisões arquiteturais continuam sendo discutidas antes de serem implementadas.

Mais adiante, quero realizar um experimento concreto: solicitar a migração da integração Symfony para Laravel, preservando o código independente do framework tanto quanto possível.

A intenção não é provar antecipadamente que a arquitetura funcionará. Quero observar o que realmente precisará mudar, onde surgirão dificuldades e quanto a separação adotada ajudará ou atrapalhará o trabalho do agente.

Esse experimento ainda não aconteceu.

Por enquanto, temos uma hipótese que poderá ser testada quando existir uma aplicação com comportamento real.

O próximo passo: finalmente escrever código de negócio#

Depois das mudanças iniciais, o próximo marco é deliberadamente simples: implementar o caso de uso de criação de pedidos.

A primeira versão deverá persistir o pedido e seus itens em uma transação PostgreSQL, sem Kafka e sem introduzir abstrações desnecessárias.

A partir desse fluxo, poderemos observar onde ficam as regras de negócio, quais contratos a aplicação realmente precisa e como o Symfony se integra a ela.

Somente depois de validar esse comportamento introduziremos a comunicação assíncrona e começaremos a comparar as duas abordagens.

A meta não é construir uma arquitetura perfeita antes de começar. É construir algo pequeno o suficiente para entender, testar e modificar.

Um laboratório em andamento#

Em poucos dias, o projeto mudou de stack, teve sua estrutura reorganizada e acumulou algumas decisões arquiteturais importantes.

Isso pode parecer preparação demais para quem espera ver uma funcionalidade pronta. E existe, de fato, o risco de passar mais tempo preparando o laboratório do que realizando os experimentos.

Por isso, o próximo marco está definido: sair da infraestrutura e chegar ao primeiro caso de uso funcional.

O repositório registra as mudanças no código. Este espaço servirá para registrar o raciocínio por trás delas, as hipóteses, os resultados e as decisões que precisarem ser revistas.

Não há uma arquitetura definitiva para apresentar, nem resultados de desempenho para anunciar.

Há um experimento em andamento e uma intenção: entender a arquitetura orientada a eventos construindo um sistema, observando seu comportamento e questionando as próprias escolhas.

É por aí que vamos começar.


Este artigo foi elaborado com auxílio de inteligência artificial e revisado pelo autor. As decisões, o estado do projeto e os experimentos descritos correspondem ao trabalho realizado até 19 de outubro de 2026.