Skip to content

Event-Driven Architecture

  • Event Driven Architecture(EDA) is a software design pattern where the flow of program is determined by the events.
  • An event can be anything : a user action(click, request), a message from another service, or even a timer.
  • Instead of executing a code sequentially, the systems listens to events and executes handlers when they occur.
  • ๐Ÿ‘‰ In Node.js, this is possible because Node.js is built on the libuv event loop and Event Emitter.
  • libuv is a cross-platform, open-source C library that provides asynchronous I/O & event-driven programming compatibilities.
  • Node.js runs on single thread.
  • Instead of blocking for I/O(file read, DB query, HTTP requests), it registers a callback/event handler.
  • When the operation completes, an event is emitted, and the callback is executed.
  • โšก This is what makes Node.js non-blocking and efficient for I/O heavy architecture.
  • The events module in Node.js allows you to implement event-driven architecture easily.
  • Example :
import EventEmitter from 'events';
const myEvent = new EventEmitter();
// Listener (subscriber)
myEvent.on('userRegister', (user)=>{
console.log(`User registered: ${user.name}`)
})
// Emit an event (publisher)
myEvent.emit('userRegister', {name: 'Sonam', email: 'sonam@gmail.com'});
  • ๐Ÿ‘‰ Output: User registered: Sonam
  • emit()= raises an event.
  • on() = listens for the event.
  • Imagine a user registration API:
const express = require("express");
const EventEmitter = require("events");
const app = express();
const eventBus = new EventEmitter();
app.use(express.json());
// Listener: send welcome email
eventBus.on("userRegistered", (user) => {
console.log(`๐Ÿ“ง Sending welcome email to ${user.email}`);
});
// Listener: log analytics
eventBus.on("userRegistered", (user) => {
console.log(`๐Ÿ“Š Tracking signup for user: ${user.name}`);
});
// API endpoint
app.post("/register", (req, res) => {
const user = req.body;
console.log(`โœ… User ${user.name} registered`);
// Emit event (triggers multiple listeners)
eventBus.emit("userRegistered", user);
res.status(201).send("User registered successfully!");
});
app.listen(3000, () => console.log("Server running on port 3000"));
  • ๐Ÿ‘‰ When a user registers, multiple actions happen asynchronously (send email, track analytics) without blocking the main flow.
  • โœ… Loose coupling โ†’ Publishers donโ€™t need to know who is listening.
  • โœ… Scalability โ†’ Easy to add new listeners without changing existing code.
  • โœ… Asynchronous & non-blocking โ†’ Handles high concurrency well.
  • โœ… Extensibility โ†’ Perfect for microservices with message queues (Kafka, RabbitMQ, Redis Pub/Sub).
  • Node.js internals โ†’ HTTP server, Streams, File I/O are all event-driven.
  • Real-time apps โ†’ Chat apps, gaming, IoT.
  • Microservices โ†’ Services emit events, others react (via Kafka, RabbitMQ, SNS/SQS).
  • Monitoring/logging โ†’ Trigger alerts when an event occurs.
  • Event-driven = โ€œDoorbell systemโ€ โ†’ You press the bell (event), it triggers actions (dog barks, notification sound, camera turns on).
  • Traditional (sequential) = โ€œPollingโ€ โ†’ Someone keeps opening the door every second to check if someone is outside (wasteful).