hub

Event-Driven
Architecture

Stop asking "What should I do next?" and start shouting "I just did something!". Inverting control flow to decouple services.

Why Events?

Request-Driven (Command)

OrderService → PaymentService

"Hey Payment Service, charge this card."
(Coupling: OrderService MUST know PaymentService exists.)

Event-Driven (Notification)

OrderService → Broker

"I just created an order."
(Decoupling: OrderService doesn't care who listens.)

The Benefit

You can add new functionality without changing existing code.

  • Want to send an email? Add an Email Listener.
  • Want to update analytics? Add an Analytics Listener.
  • Want to trigger shipping? Add a Shipping Listener.

The Order Service changes exactly zero lines of code.

Producer-Consumer Pattern

upload
Producer
Emits Event
arrow_forward
Message Queue
arrow_forward
download
Consumer A
download
Consumer B
Consumers process events asynchronously. They can scale independently from Producers.

Choreography vs Orchestration

How do services coordinate complex workflows?

Choreography (Dance)

Decentralized

Each service knows what to do when an event happens. No central manager.

1. Order: "OrderCreated"
2. Payment: (hears event) → Charges → "PaymentProcessed"
3. Shipping: (hears event) → Ships → "ItemShipped"
Pro: Loose coupling.
Con: Hard to visualize the whole process.

Orchestration (Conductor)

Centralized

A central "Orchestrator" service tells everyone what to do.

1. Order: Tells Payment "Charge now"
2. Payment: "Done"
3. Order: Tells Shipping "Ship now"
4. Shipping: "Done"
Pro: Easy to track state and errors.
Con: Tight coupling. Order service becomes a "God Service".

Event Sourcing

history_edu

Store Events, Not State

Traditional (CRUD)

// Users Table
ID: 1
Balance: 100 150

We overwrote the old balance. History is lost.

Event Sourcing

// Event Log
1. AccountCreated (0)
2. Deposited (100)
3. Deposited (50)
Current State = Sum(Events) = 150

We store the sequence of changes. We can replay history to debug.

CQRS

Command Query Responsibility Segregation. Separating the model for updating information (Command) from the model for reading information (Query).

Command Model

Optimized for Writes / Logic.

INSERT INTO orders...
Usually normalized (3NF) to ensure data integrity.

Query Model

Optimized for Reads / Views.

SELECT * FROM order_view...
Usually denormalized (NoSQL, Materialized View) for speed.

The Command side publishes events. The Query side listens to events and updates its read-optimized views. (Eventual Consistency).