Wolverine for messaging
The problem it solves
Domains must react to one another — an invitation creates a notification, a deleted organization cancels its subscription — without calling one another. And the reaction must happen if and only if the change committed: an audit entry for a change that rolled back, or a lost webhook for one that succeeded, are both bugs.
That takes a message bus with a transactional outbox: the message is written in the same database transaction as the change, and sent once it commits.
Wolverine provides that outbox natively on EF Core and PostgreSQL, with RabbitMQ as the transport, exponential retries and dead-letter queues. Its core and the extensions the Starter uses are under the MIT licence. The Starter used MassTransit before; MassTransit became commercial with its version 9, and Wolverine replaced it with the same events and the same guarantees.
What it costs
- A broker to run — RabbitMQ, in development and in production.
- Eventual consistency across domains: a notification appears a moment after the invitation, not in the same transaction.
- Outbox tables in their own schemas, built by the migration runner.
- Some configuration is the Starter's own: Wolverine generates handler code by
default; the Starter turns that off and registers each consumer explicitly, so that
consumers can stay
internaland nothing is compiled at runtime.
What you can relax
- Change the transport or the library in one place. Only
Blouppy.Infrastructure.Messagingreferences Wolverine (BusLibraryBoundaryTestsenforces it); the domains use the Starter's ownIIntegrationEventPublisher<T>andIIntegrationEventHandler<T>. - Keep a reaction synchronous when it must hold before the change: that is what
domain events — inside the transaction — and
.PublicDatacontracts are for. Not everything needs the bus.