Skip to main content

DDD: Domain Events — Facts Your Domain Announces

Immutable facts that happened in your domain, named in past tense, published after a state change commits.

When to use

  • Notifying other bounded contexts of state changes without coupling
  • Triggering side effects (emails, projections, integrations)
  • Building an audit trail

Tradeoffs

  • Eventual consistency — consumers lag behind the write
  • Event schema becomes a contract between contexts (coupling at the schema level)
type OrderPlaced struct {
OrderID string
CustomerID string
OccurredAt time.Time
}

type EventPublisher interface {
Publish(event any) error
}

func (o *Order) Place(pub EventPublisher) error {
o.Status = "placed"
// publish AFTER state change — caller commits DB tx first
return pub.Publish(OrderPlaced{
OrderID: o.ID, CustomerID: o.CustomerID, OccurredAt: time.Now(),
})
}

Gotcha: Publish events AFTER the transaction commits — not inside it. Otherwise you publish events for transactions that roll back.