Coupling is the tax you pay on every future change. Event-driven architecture lowers that tax by letting producers stay ignorant of their consumers.
The core idea
A service emits a fact — “OrderPlaced” — and other services decide what to do with it. Nobody calls anybody directly.
await bus.publish({
type: 'OrderPlaced',
payload: { orderId, total, currency },
})
<h2 id="make-failures-survivable">Make failures survivable</h2>
<p>Consumers must be idempotent. The same event can be delivered more than once, and your handler has to be bored by that fact.</p>
<p>:::warning
Never put side effects before you have persisted the event. If you crash between the two, you lose work with no recovery path.
:::</p>
<h2 id="why-it-pays-off">Why it pays off</h2>
<ul>
<li>New features attach as new consumers, not new call sites</li>
<li>Failures are localized to a single handler</li>
<li>The event log becomes a debugging and audit trail for free</li>
</ul>
<blockquote>
<p>Design for the event you can replay, not the request you can retry.</p>
</blockquote>
Comments
Comments are disabled for now. We're preparing a first-class experience powered by Giscus, Disqus or GitHub Discussions.