docs/layouts/index.html
{{ define "main" }}
{{ .Params.lead | safeHTML }}
Get StartedSee on GitHub {{ .Content }}
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" "" }}
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" "" }}
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" "" }}
Work with Kafka, RabbitMQ, PostgreSQL, Redis, and more Pub/Subs with the same API. Switch providers without changing your application code.
AWS SNS/SQS BoltDB Firestore Go Channel Google Cloud Pub/Sub HTTP I/O Kafka MySQL NATS PostgreSQL RabbitMQ Redis SQLite
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" "" }}
{{ end }} {{ define "sidebar-prefooter" }} {{ if site.Params.doks.backgroundDots -}}
{{ end -}} {{ end }} {{ define "sidebar-footer" }} {{ if site.Params.doks.sectionFooter -}}
{{ end -}} {{ end }}