{{ define "main" }}
Logo

{{ .Title }}

{{ .Params.lead | safeHTML }}

Get Started See on GitHub {{ .Content }}

Publish Events

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

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

Handle Events

Focus on the business logic.
Watermill handles routing, serialization and low-level details.

{{ highlight `eventProcessor.AddHandlers( cqrs.NewEventHandler("SendWelcomeEmail", sendWelcomeEmail), ) func sendWelcomeEmail(ctx context.Context, event *UserRegistered) error { return emailService.Send(event.Email, "Welcome!") }` "go" "" }}

Simple API you already know

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

{{ highlight `router.AddMiddleware( middleware.Recoverer, middleware.CorrelationID, middleware.Timeout(30 * time.Second), )` "go" "" }}

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.

{{ highlight `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{...}) // ... }` "go" "" }}
Watermill Logo

Start building

{{ end }} {{ define "sidebar-prefooter" }} {{ if site.Params.doks.backgroundDots -}}
{{ end -}} {{ end }} {{ define "sidebar-footer" }} {{ if site.Params.doks.sectionFooter -}}

Start building with Doks today

{{ i18n "get-started" }}
{{ end -}} {{ end }}