Event Driven Architecture in Node-Express : A Detailed Guide

Other Blogs

Blogs ❯❯ NodeJS

Image could not load

Event Driven Architecture In Node.js

Node.js and Express.js framework को use करके जब हम Event Driven Architecture (EDA) implement करते हैं, तो हम अपने applications को और ज़्यादा scalable और decoupled बना सकते हैं।

इस architecture में components एक दूसरे से directly communicate नहीं करते, बल्कि events emit करते हैं जो किसी listener के through asynchronously handle किये जाते हैं।

इस blog post में हम Event Driven Architecture (EDA) को Node.js और Express के context में समझेंगे, एक real-world example के through — Product CRUD (Create, Read, Update, Delete) application का use करेंगे।

साथ ही, हम events और उनके components को समझेंगे और कैसे EDA को efficiently implement किया जा सकता है ।

What is Event Driven Architecture ?

Event Driven Architecture एक design pattern है जिसमे application के components एक दूसरे के साथ directly communicate नहीं करते, बल्कि events का use करके communicate करते हैं।

जब कोई event trigger होता है, तो system के listeners उस event को handle करते हैं। यह approach especially useful होता है जब आपको high concurrency handle करनी हो और application को loosely coupled banana हो।

Components of Event Driven Architecture

  1. Event Emitters : यह वो components होते हैं जो किसी action या activity के complete hone पर events को emit करते हैं। जैसे product create hone पर एक "Product Created" event emit करना।

  2. Event Listeners : यह components वो होते हैं जो किसी event को सुनते हैं और जब वो event trigger होता है, तब अपना action execute करते हैं। जैसे product create hone पर email notification भेजना या log update करना।

  3. Event : यह एक signal होता है जो किसी specific action या event का indicator होता है, जैसे "ProductCreated" event.

Event Driven Example In Node

चलिए, एक Product CRUD module बनाते हैं जिसमे हम CRUD operations perform करेंगे और हर operation के बाद एक specific event emit करेंगे (like product created, product updated, etc.).

इस example में हम Express.js को server के लिए use करेंगे, MongoDB को data store करने के लिए, और Node's EventEmitter को event-driven logic handle करने के लिए।

Step 1 : Project Setup

सबसे पहले, एक new Node.js project create करते हैं।

mkdir event-driven-crud
cd event-driven-crud
npm init -y
npm install express mongoose
Step 2 : Define the Product Model

हम Mongoose को use करेंगे ताकि MongoDB के साथ interact कर सकें।

// models/Product.js const mongoose = require('mongoose'); const productSchema = new mongoose.Schema({ name: { type: String, required: true }, price: { type: Number, required: true }, description: { type: String, required: true } }); const Product = mongoose.model('Product', productSchema); module.exports = Product;
Step 3 : Implementing EventEmitter

अब हम Node.js’s built-in EventEmitter class का use करेंगे, जिसमे events emit करेंगे जब भी कोई CRUD operation complete होगा।

// services/eventEmitter.js const EventEmitter = require('events'); class ProductEventEmitter extends EventEmitter {} const productEventEmitter = new ProductEventEmitter(); // Event listeners productEventEmitter.on('productCreated', (product) => { console.log('Product Created:', product.name); // Example: Send an email, update cache, etc. }); productEventEmitter.on('productUpdated', (product) => { console.log('Product Updated:', product.name); // Example: Send update notification, etc. }); productEventEmitter.on('productDeleted', (productId) => { console.log('Product Deleted with ID:', productId); // Example: Clean up resources, etc. }); module.exports = productEventEmitter;
Step 4 : CRUD Operations with Event Emitting

अब हम अपने Express.js routes implement करते हैं जहाँ हर CRUD operation के बाद एक event emit होगा।

// server.js const express = require('express'); const mongoose = require('mongoose'); const Product = require('./models/Product'); const productEventEmitter = require('./services/eventEmitter'); const app = express(); app.use(express.json()); // Connect to MongoDB mongoose.connect('mongodb://localhost:27017/productdb', { useNewUrlParser: true, useUnifiedTopology: true }) .then(() => console.log('Connected to MongoDB')) .catch(err => console.error('MongoDB connection error:', err)); // CREATE a new product app.post('/products', async (req, res) => { try { const { name, price, description } = req.body; const newProduct = new Product({ name, price, description }); await newProduct.save(); // Emit 'productCreated' event productEventEmitter.emit('productCreated', newProduct); res.status(201).json(newProduct); } catch (err) { res.status(500).json({ message: 'Error creating product', error: err }); } }); // READ all products app.get('/products', async (req, res) => { try { const products = await Product.find(); res.status(200).json(products); } catch (err) { res.status(500).json({ message: 'Error fetching products', error: err }); } }); // UPDATE a product app.put('/products/:id', async (req, res) => { try { const { id } = req.params; const { name, price, description } = req.body; const updatedProduct = await Product.findByIdAndUpdate(id, { name, price, description }, { new: true }); if (!updatedProduct) { return res.status(404).json({ message: 'Product not found' }); } // Emit 'productUpdated' event productEventEmitter.emit('productUpdated', updatedProduct); res.status(200).json(updatedProduct); } catch (err) { res.status(500).json({ message: 'Error updating product', error: err }); } }); // DELETE a product app.delete('/products/:id', async (req, res) => { try { const { id } = req.params; const deletedProduct = await Product.findByIdAndDelete(id); if (!deletedProduct) { return res.status(404).json({ message: 'Product not found' }); } // Emit 'productDeleted' event productEventEmitter.emit('productDeleted', id); res.status(200).json({ message: 'Product deleted successfully' }); } catch (err) { res.status(500).json({ message: 'Error deleting product', error: err }); } }); // Start the server const PORT = process.env.PORT || 3000; app.listen(PORT, () => { console.log(`Server running on port ${PORT}`); });

How the Event-Driven architecture works in above example

  • Event Emitters : हमने ProductEventEmitter का use किया है जो CRUD operations के बाद events emit करता है। जैसे ही product create होता है, productCreated event trigger होता है।

  • Event Listeners : हर event के लिए हमने एक listener define किया है जो event trigger hone पर अपना काम करेगा। जैसे productCreated event trigger होता है, उसका listener product का नाम console पर print करता है।

  • Decoupled Operations : CRUD operation और side effects (जैसे email भेजना, logging, etc.) को हमने decouple कर दिया है। अगर एक listener fail होता है, तो CRUD operation पर कोई effect नहीं पड़ता।

  • Asynchronous Handling : Event listeners asynchronously handle होते हैं। इससे application non-blocking हो जाता है और performance भी improve होती है।

Benefits of Event Driven Architecture

  1. Scalability : इसमें components independently scale कर सकते हैं। जब आपको एक event को handle करना होता है, तो आप उसके listener को independently scale कर सकते हैं।

  2. Loosely Coupled Components : Components एक दूसरे से tightly coupled नहीं होते, अगर एक component fail हो जाता है, तो बाकी components का काम continue रहता है।

  3. Asynchronous Execution : EDA asynchronous होता है, जो performance improve करता है, आपको events handle करते वक्त blocking operations नहीं करते।

Hey ! I'm Rahul founder of learnhindituts.com. Working in IT industry more than 5.5 years. I love to talk about programming as well as writing technical tutorials and blogs that can help to others .... keep learning :)

Get connected with me - LinkedIn Twitter Instagram Facebook

Your Thought ?

Please wait . . .

    Recent Blogs

    Loading ...

    0 Comment(s) found !