Title here
Summary here
Work with Go structs.
Decouple your services with asynchronous processing.
event := UserRegistered{
UserID: id,
Email: email,
JoinedAt: time.Now(),
}
err := eventBus.Publish(ctx, event)
Focus on the business logic.
Watermill handles routing, serialization and low-level details.
eventProcessor.AddHandlers(
cqrs.NewEventHandler("SendWelcomeEmail", sendWelcomeEmail),
)
func sendWelcomeEmail(ctx context.Context, event *UserRegistered) error {
return emailService.Send(event.Email, "Welcome!")
}
Use the familiar concepts, similar to an HTTP Router with support for middleware.
router.AddMiddleware(
middleware.Recoverer,
middleware.CorrelationID,
middleware.Timeout(30 * time.Second),
)
Work with Kafka, RabbitMQ, PostgreSQL, Redis, and more Pub/Subs with the same API. Switch providers without changing your application code.
Use any architecture you want. No vendor lock-in.
func (h *Handler) RegisterUser(w http.ResponseWriter, r *http.Request) {
user := createUser(r)
// Your existing business logic
err := h.userRepo.Save(user)
if err != nil {
// ...
}
// Publish an event using Watermill
err := h.eventBus.Publish(r.Context(), &UserRegistered{...})
// ...
}