The Transactional Outbox and Inbox patterns are essential building blocks for ensuring reliable, decoupled communication between bounded contexts in a Domain-Driven Design (DDD) architecture (even within a modular monolith).
The Transactional Outbox pattern guarantees atomicity and consistency between the domain model and the integration layer. When an aggregate’s state changes, the corresponding events are recorded in an outbox table as part of the same database transaction. This ensures that either both the state change and the event persist successfully, or neither does, eliminating the risk of publishing inconsistent messages.
The Inbox pattern, on the other hand, ensures idempotent and reliable event consumption. Each incoming message is logged in an inbox table before it is processed. If the same message is redelivered (for example, due to retries, network issues, or system restarts), the system can detect and skip duplicates based on the message’s unique identifier. This preserves the integrity of the domain while supporting exactly-once semantics at the business level.
By combining Outbox and Inbox, you maintain strong consistency within each bounded context and eventual consistency across them,a key property for scaling complex business systems while keeping the codebase modular, maintainable, and aligned with the domain model.
Run the following command:
make installRun the following command:
make upMake a POST HTTP request on http://localhost:3000/users/ with the following payload :
{
"email": "[email protected]",
"password": "@Str0ng4Passrez!"
}Run the dedicated consumer with the following command:
make consume-user-createdRun the dedicated command with the following command:
make auth-process-outbox