Logo

Watermill

Building event-driven applications the easy way in Go.

Get Started See on GitHub

Publish Events

Work with Go structs.
Decouple your services with asynchronous processing.

event := UserRegistered{  UserID: id,  Email: email,  JoinedAt: time.Now(), }  err := eventBus.Publish(ctx, event)

Handle Events

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!") }

Simple API you already know

Use the familiar concepts, similar to an HTTP Router with support for middleware.

router.AddMiddleware(  middleware.Recoverer,  middleware.CorrelationID,  middleware.Timeout(30 * time.Second), )

Use your favorite Pub/Sub

Work with Kafka, RabbitMQ, PostgreSQL, Redis, and more Pub/Subs with the same API. Switch providers without changing your application code.

Library ≠ Framework

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{...})  // ... }
Watermill Logo

Start building