What is a domain event, and how is it different from an integration event?

SOLID & Design Patterns Architecture Advanced 3–5 Yrs5+ Yrs Architecture 1 min read

Quick Answer

A domain event — something that happened inside the domain that other parts of the same process might care about (OrderShipped) — dispatched in-process (MediatR notification), usually right after the transaction commits. An integration event is the version published outside the process, onto a message bus, for other services to consume — a different message, often derived from the domain event, since other services shouldn't depend on your internal model.

A domain event represents something meaningful that happened to an aggregate — OrderShipped, PaymentFailed — and it's handled entirely within the same process, usually via something like MediatR notifications, so other parts of the app can react without the aggregate itself knowing or caring who's listening. I dispatch them after the database transaction actually commits, because reacting to something that then gets rolled back is a real bug. An integration event is a different, outward-facing thing — it's what you publish to a message bus so other services can react, and it's usually a deliberately separate, versioned message rather than your raw domain event, because you don't want other teams coupled to your internal model. A common pattern is: domain event fires internally, one of its handlers is the thing that publishes the corresponding integration event via the outbox for reliable delivery.

  • Pattern: aggregate collects domain events during a business operation; after SaveChanges succeeds, an interceptor dispatches them to in-process handlers.
  • Don't dispatch domain events before the transaction commits — a handler acting on data that then rolls back is a real bug.
  • Integration events go through the outbox pattern for reliable delivery to other services, and are versioned/stable contracts, unlike internal domain events which can change freely.
  • Keeps “send a confirmation email when an order ships” decoupled from the order-shipping code itself.