Event Sourcing & CQRS · Evolution and Compliance

Domain Events vs Integration Events

What stays inside a service and what you publish to others.

Domain events are internal facts used by the owning service (fine-grained, can change with the model). Integration events are a public contract published to other services — stable, versioned, documented (AsyncAPI), containing only what consumers need, often coarser. Translate domain events into integration events at the boundary (via outbox) so internal refactoring doesn't break other teams.

Two kinds of events

Criterion Domain events Integration events
Audience Same service / bounded context Other services/teams
Stability Can evolve with the model Versioned public contract
Granularity Fine-grained Coarser, consumer-oriented
Transport Event store / in-process Broker (Kafka, SNS) via outbox
Schema governance Team-internal Registry + compatibility checks
Domain events (orders service, internal):
  OrderLineAdded, OrderLineRemoved, ShippingAddressCorrected, OrderPlaced
Integration event (published, v1 contract):
  orders.order-placed.v1 {order_id, customer_id, lines:[{sku, qty}], total, currency, placed_at}

Common pitfalls

  • Publishing internal events directly (other teams couple to your model).
  • Integration events missing data consumers need (forcing callbacks).
  • No versioning for public events.

Key points

  • Domain events internal
  • Integration events = public contract
  • Translate at the boundary

Further reading: Microsoft: Domain events design

Practice questions

Why not publish every domain event to Kafka for other teams?

Answer

Other teams would couple to your internal model; any refactoring of internal events becomes a breaking change across the organization.

What makes a good integration event payload?

Answer

Stable, versioned fields consumers actually need (IDs, key facts, amounts, timestamps), so they rarely need to call back to the producer.

Open in the app to mark lessons complete, take notes and track your progress.