Desvendando Event-Driven Architecture e Mensageria em Go com Watermill
Davi Orlandi

Davi Orlandi @dvorlandi

About: Hi 👋! My name is Davi Orlandi, and i'm a software developer.

Location:
Brasil
Joined:
Jul 4, 2024

Desvendando Event-Driven Architecture e Mensageria em Go com Watermill

Publish Date: May 29
1 0

O que é o Watermill?

O Watermill é uma biblioteca open-source para Go, criada para facilitar o desenvolvimento de aplicações baseadas em eventos e mensagens. Ele abstrai a complexidade dos principais brokers do mercado (Kafka, RabbitMQ, NATS, Google Pub/Sub, Redis Streams, entre outros), oferecendo uma API unificada, simples e extensível. Com o Watermill, você pode construir pipelines de mensagens robustos, escaláveis e resilientes, sem se preocupar com os detalhes de cada sistema de mensageria.


Por que usar Watermill?

Sistemas baseados em eventos trazem vantagens como desacoplamento, escalabilidade horizontal e facilidade para implementar padrões como CQRS e Event Sourcing. O Watermill resolve problemas comuns desse tipo de arquitetura, como:

  • Abstração dos brokers: troque Kafka por RabbitMQ (ou vice-versa) sem reescrever sua lógica.
  • Middleware plugável: adicione logging, retries, métricas e outras funcionalidades de forma simples.
  • Performance: processa centenas de milhares de mensagens por segundo, aproveitando o modelo concorrente do Go.
  • Testabilidade: suporte a brokers em memória para testes locais rápidos.

Principais Componentes do Watermill

O Watermill é construído em torno de quatro conceitos principais:

  • Publisher: responsável por publicar mensagens em um tópico.
  • Subscriber: consome mensagens de um tópico.
  • Router: roteia mensagens entre publishers e subscribers, aplicando middlewares e handlers.
  • Middleware: adiciona funcionalidades transversais, como logging, retries, limitação de taxa, etc.

Esses componentes se conectam de forma flexível, permitindo criar desde fluxos simples até pipelines complexos de processamento de eventos.


Protocolos e Brokers Suportados

O Watermill suporta, de forma oficial, os principais sistemas de mensageria do mercado:

  • Kafka
  • RabbitMQ (AMQP)
  • Google Cloud Pub/Sub
  • AWS SNS/SQS
  • Redis Streams
  • SQL (PostgreSQL, MySQL)
  • GoChannel (in-memory, ótimo para testes)
  • HTTP

Isso significa que você pode começar com um broker simples e migrar para algo mais robusto conforme sua aplicação cresce, sem grandes mudanças no código.


Exemplo Prático: Publicando e Consumindo Mensagens com Kafka

Vamos ver um exemplo básico de como publicar e consumir mensagens usando Watermill com Kafka. O mesmo padrão vale para outros brokers, mudando apenas a configuração.

Pré-requisitos:

  • Go instalado
  • Docker rodando Kafka localmente (veja docker-compose aqui)
  • Dependências instaladas:
  go get github.com/ThreeDotsLabs/watermill
  go get github.com/ThreeDotsLabs/watermill-kafka/v3
Enter fullscreen mode Exit fullscreen mode

Publisher:

package main

import (
    "github.com/ThreeDotsLabs/watermill"
    "github.com/ThreeDotsLabs/watermill-kafka/v3/pkg/kafka"
    "github.com/ThreeDotsLabs/watermill/message"
    "log"
)

func main() {
    logger := watermill.NewStdLogger(false, false)
    publisher, err := kafka.NewPublisher(
        kafka.PublisherConfig{
            Brokers:   []string{"localhost:9092"},
            Marshaler: kafka.DefaultMarshaler{},
        },
        logger,
    )
    if err != nil {
        log.Fatal(err)
    }

    msg := message.NewMessage(watermill.NewUUID(), []byte("Olá, Watermill!"))
    if err := publisher.Publish("exemplo.topico", msg); err != nil {
        log.Fatal(err)
    }
    log.Println("Mensagem publicada!")
}
Enter fullscreen mode Exit fullscreen mode

Subscriber:

package main

import (
    "context"
    "github.com/ThreeDotsLabs/watermill"
    "github.com/ThreeDotsLabs/watermill-kafka/v3/pkg/kafka"
    "github.com/ThreeDotsLabs/watermill/message"
    "log"
)

func main() {
    logger := watermill.NewStdLogger(false, false)
    subscriber, err := kafka.NewSubscriber(
        kafka.SubscriberConfig{
            Brokers:       []string{"localhost:9092"},
            Unmarshaler:   kafka.DefaultMarshaler{},
            ConsumerGroup: "exemplo-grupo",
        },
        logger,
    )
    if err != nil {
        log.Fatal(err)
    }

    messages, err := subscriber.Subscribe(context.Background(), "exemplo.topico")
    if err != nil {
        log.Fatal(err)
    }

    for msg := range messages {
        log.Printf("Mensagem recebida: %s", string(msg.Payload))
        msg.Ack()
    }
}
Enter fullscreen mode Exit fullscreen mode

Dica:

Para testar localmente, rode o Kafka com Docker, execute o subscriber e depois o publisher. Você verá as mensagens fluindo entre eles.


Casos de Uso e Vantagens

O Watermill é ideal para:

  • Microsserviços que precisam se comunicar de forma assíncrona e desacoplada.
  • Sistemas de processamento de eventos em tempo real (monitoramento, analytics, notificações).
  • Implementação de padrões como CQRS e Event Sourcing.
  • Projetos que exigem escalabilidade horizontal e resiliência.

Entre as vantagens, destacam-se a flexibilidade (suporte a múltiplos brokers), performance, API intuitiva e facilidade de integração com middlewares e métricas (Prometheus).


Conclusão

O Watermill é uma excelente escolha para quem quer adotar event-driven architecture e mensageria em Go. Ele abstrai a complexidade dos brokers, oferece uma API poderosa e flexível, e permite construir sistemas modernos, escaláveis e resilientes. Se você quer dar o próximo passo na arquitetura do seu projeto Go, vale muito a pena experimentar o Watermill.

Links úteis:

Se ficou com dúvidas ou quer compartilhar sua experiência com Watermill, deixe um comentário!

Comments 0 total

    Add comment