August 29, 2026 | Edit
Crossing Boundaries with Integration Events
This article is a part of an ongoing series on Domain-Driven Design.
You can check out the rest of the series here.
This article is about everything that has to go right for one bounded context to tell another that something happened - and how to design for the ways it goes wrong.
In Modeling Facts and Reactions with Domain Events, we saw how a domain event records a meaningful business fact inside the model where that fact became true. It can trigger local reactions, but its name, types, and payload belong to that domain model and are free to evolve with it. We can think of domain events as internal events. Here we cover what happens when a fact must cross into another bounded context: a model with its own language and responsibilities.
Crossing the boundary
Suppose Ordering and Fulfillment are independently owned and deployed contexts, and Fulfillment needs to prepare a newly placed order. They need a stable public contract containing the business information that Fulfillment requires, without coupling it to Ordering’s internal model. This contract is an integration event, which we can think of as an external event.
Integration events travel over durable asynchronous messaging, using infrastructure such as Apache Kafka, RabbitMQ, or Azure Service Bus, so Ordering can finish without waiting for Fulfillment. Each context can process work at its own pace, temporary outages do not have to propagate back to the producer, and messages can remain available until a consumer is ready to handle them.
These benefits come with new challenges: either context may be unavailable, messages may be delayed or duplicated, and the two contexts cannot share a database transaction. We therefore have two problems to solve:
... continue reading