Sem API-to-API
Ingestão e consolidação são limites independentes. A leitura não deve depender da disponibilidade da API de escrita.
Estudo de caso arquitetural · laboratório público
O dotnet-observability-lab é uma reference architecture educacional que uso para tornar verificável uma linha completa de raciocínio: problema → restrições → atributos de qualidade → decisões → implementação → falhas → observabilidade → evidências.
Esta página é uma leitura de portfólio. A documentação técnica canônica permanece no repositório do laboratório.
Problema
Uma API recebe um valor e precisa aceitá-lo de forma durável e idempotente. Outro limite de serviço deve consolidar esse valor de forma assíncrona, sem chamada HTTP entre APIs e sem transformar uma redelivery do broker em duplicação de negócio.
A dificuldade real não está no valor decimal. Está no intervalo entre persistir, publicar, consumir, confirmar e recuperar — inclusive quando não é possível saber com certeza se a etapa anterior terminou.
Restrições e atributos de qualidade
Ingestão e consolidação são limites independentes. A leitura não deve depender da disponibilidade da API de escrita.
RabbitMQ pode redeliver. Duplicatas fazem parte do contrato e precisam ser tratadas como comportamento normal.
PostgreSQL protege idempotência, Outbox, Inbox e agregado. Redis é apenas um atalho best-effort.
OpenTelemetry define traces, métricas e logs. Aspire compõe e exibe o ambiente local, mas não roteia tráfego de negócio.
Decisões e trade-offs
RabbitMQ desacopla disponibilidade e latência entre ingestão e consolidação.
Trade-off: consistência eventual e maior custo operacional.
ADR 0004 ↗Valor e evento pendente são persistidos na mesma transação; um worker publica depois com confirmação do broker.
Trade-off: polling, retry, quarentena e possibilidade de publicação repetida.
Implementação ↗Identidade da mensagem e atualização do agregado são confirmadas na mesma transação PostgreSQL.
Trade-off: toda mensagem única exige trabalho durável e política futura de retenção.
Implementação ↗O desenho não promete exactly-once. Ele torna repetição segura no efeito de negócio.
Trade-off: cada consumidor precisa tratar identidade e duplicação explicitamente.
Contrato do evento ↗Cache reduz custo de repetição HTTP, mas queda, expiração ou eviction não podem alterar a correção.
Trade-off: misses e falhas ainda podem tocar o banco.
ADR 0003 ↗Contexto W3C atravessa a fronteira assíncrona; Aspire é uma das superfícies locais de inspeção.
Trade-off: propagação e instrumentação precisam ser mantidas explicitamente.
ADR 0005 ↗Fluxo nominal
Falhas relevantes
Mesmo key + mesmo valor retorna o recibo original; uso conflitante retorna 409. A restrição única no PostgreSQL resolve corrida concorrente.
A Inbox impede segundo efeito de negócio. A mensagem pode ser consumida mais de uma vez sem incrementar o agregado novamente.
A API ainda pode aceitar e persistir a escrita. O Outbox mantém trabalho pendente para publicação posterior.
O fast path desaparece, mas a correção não. A decisão de idempotência volta ao PostgreSQL.
O evento pode ser republicado com a mesma identidade; o consumidor trata a duplicata de forma segura.
Inbox e agregado fazem rollback juntos. Não fica um marcador falso de processamento concluído.
Observabilidade
O contexto W3C iniciado na requisição é persistido junto ao Outbox, reiniciado pelo worker de publicação e propagado por headers AMQP até o consumidor. Métricas de baixa cardinalidade diferenciam aceitação, publicação, processamento e duplicação; logs estruturados registram resultados operacionais relevantes.
O objetivo não é “ter dashboards”. É conseguir explicar por que uma escrita ainda não apareceu no modelo de leitura e localizar a fronteira onde o fluxo está parado ou repetindo.
Ver testes de traces e métricas ↗Evidências públicas
Limites deliberados
O laboratório mantém um único PostgreSQL local com bancos lógicos separados, não define plataforma de deploy de produção e não implementa no v1 uma política completa de bounded retry/DLQ no consumidor. Também não promete ordenação de eventos nem exactly-once.
Esses limites são parte da evidência: mostram o que foi decidido, o que foi simplificado para fins educacionais e quais decisões precisariam ser reabertas em um sistema real.
Explorar o repositório completo ↗