Event-Driven Architecture (EDA) adalah pola arsitektur di mana komponen-komponen sistem berkomunikasi melalui event — notifikasi bahwa sesuatu telah terjadi.
Konsep dasar:
Producer Event Bus / Broker Consumer
(pengirim) ──→ "order.created" ──→ Email Service
──→ Inventory Service
──→ Analytics Service
Alih-alih service A memanggil service B secara langsung, A hanya menerbitkan event. Siapa pun yang tertarik bisa subscribe dan merespons.
Komponen EDA:
- Event — record bahwa sesuatu terjadi (
{ type: "order.created", orderId: 42, userId: 7 }) - Producer — komponen yang menerbitkan event
- Consumer — komponen yang subscribe dan merespons event
- Event Broker — sistem yang menyalurkan event (Kafka, RabbitMQ, Redis Streams)
Implementasi EventBus sederhana:
class EventBus {
constructor() {
this.subscribers = {};
}
subscribe(event, handler) {
if (!this.subscribers[event]) {
this.subscribers[event] = [];
}
this.subscribers[event].push(handler);
}
unsubscribe(event, handler) {
if (!this.subscribers[event]) return;
this.subscribers[event] = this.subscribers[event]
.filter(h => h !== handler);
}
publish(event, data) {
const handlers = this.subscribers[event] || [];
handlers.forEach(handler => handler(data));
}
}
// Penggunaan:
const bus = new EventBus();
// Email service subscribe ke order.created
bus.subscribe("order.created", ({ orderId, userId }) => {
console.log(`Kirim email konfirmasi order #${orderId} ke user ${userId}`);
});
// Inventory service juga subscribe
bus.subscribe("order.created", ({ orderId, items }) => {
console.log(`Kurangi stok untuk order #${orderId}`);
});
// Order service publish event
bus.publish("order.created", { orderId: 42, userId: 7, items: [...] });
// Kedua handler dipanggil otomatis!
Keuntungan EDA:
| Keuntungan | Penjelasan |
|---|---|
| Decoupling | Producer tidak tahu siapa yang akan merespons |
| Skalabilitas | Tambah consumer baru tanpa ubah producer |
| Resiliensi | Consumer bisa mati, event tetap tersimpan di broker |
| Audit trail | Semua event bisa di-log sebagai history |
Tantangan EDA:
- Eventual consistency — tidak ada response langsung, harus toleran terhadap delay
- Ordering — event bisa datang tidak berurutan
- Idempotency — consumer harus aman dijalankan lebih dari sekali (event bisa di-replay)
- Debugging — alur eksekusi tersebar, sulit di-trace
Pola event umum:
// Domain event — sesuatu yang terjadi di domain bisnis
{ type: "user.registered", userId: 1, email: "[email protected]", timestamp: "..." }
// Integration event — komunikasi antar bounded context
{ type: "payment.completed", orderId: 42, amount: 150000, currency: "IDR" }
// Event sourcing — event sebagai sumber kebenaran (dibahas di pelajaran berikutnya)
Tools EDA:
- Apache Kafka — throughput sangat tinggi, cocok untuk event streaming skala besar
- RabbitMQ — message broker yang mature, mendukung berbagai pola
- Redis Streams — sederhana, cocok untuk skala menengah
- AWS EventBridge — serverless event bus di cloud AWS
EDA sangat cocok untuk sistem dengan banyak consumer yang perlu merespons kejadian yang sama secara independen.
🎭 Analogi sehari-hari: Pesta ulang tahun. Ada DJ (producer) putar musik (event). Tamu yang dengar musik = consumer — bisa menari, ngobrol, makan, atau diam aja. DJ gak peduli siapa yang reaksi gimana. One-to-many broadcast tanpa coupling. Kalau orang bisu — gak ada masalah, DJ tetap putar. Kalau ada tamu baru datang — langsung ikut dengar. Tambah/hapus tamu gak ganggu DJ.
💡 Event-Driven vs Command-Driven:
- Command (request-response): "Hai service email, kirim email ini" — coupled, sync, sender tau receiver
- Event (broadcast): "User registered" — decoupled, async, sender gak tau siapa subscribe
Trade: command lebih predictable + immediate. Event lebih scalable + extensible.
⚠️ Jebakan EDA klasik:
- Lupa idempotency = event di-deliver 2x = double processing
- Event ordering matter tapi gak guarantee — pakai partition key (Kafka) atau saga ordering
- Event hilang karena consumer gak ack — wajib durable broker + ack-then-delete
- Schema evolution event payload → consumer lama break. Pakai schema registry (Avro/Protobuf)
- Debugging mimpi buruk — event terbang ke 5 service, error tracing complex. Wajib correlation ID
🎯 Kapan pakai EDA:
- Multiple consumer dengan use case berbeda untuk event yang sama (order.created → inventory + email + analytics)
- Async workflow yang butuh fault tolerance
- Audit trail wajib (event log = source of truth)
- Decouple service untuk independent deploy + scaling
❌ Hindari EDA untuk:
- Simple CRUD dengan response immediate dibutuhkan
- Sync transaction (payment processing yang butuh konfirmasi langsung)
- Team kecil + simple domain = over-engineering
TL;DR: EDA = service ber-komunikasi via event di broker (Kafka/RabbitMQ). Decoupled + scalable + extensible. Wajib idempotent consumer + correlation ID + schema registry. Cocok multi-consumer event + async workflow.