Discover how to keep your code neat while adding powerful features effortlessly!
Middleware vs decorator pattern in Node.js - When to Use Which
Imagine building a web server where you have to add logging, authentication, and error handling by writing the same code inside every function that handles requests.
Manually adding these features everywhere is tiring, easy to forget, and makes your code messy and hard to change later.
Middleware and decorator patterns let you add these extra features in one place, so your main code stays clean and you can reuse the added behavior easily.
function handleRequest(req, res) {
console.log('Request received');
if (!req.user) { res.status(401).send('Unauthorized'); return; }
try {
// main logic
} catch (e) {
res.status(500).send('Error');
}
}app.use(loggingMiddleware);
app.use(authMiddleware);
app.use(errorHandlingMiddleware);
app.get('/data', mainHandler);You can build flexible, clean, and reusable code that adds features like logging or security without touching your main logic.
Think of a coffee shop where the barista focuses on making coffee, while other staff handle taking orders, payments, and cleaning separately--each with their own role but working together smoothly.
Manual repetition of extra features is slow and error-prone.
Middleware and decorators add behavior cleanly and reuse it.
This keeps your code simple and easier to maintain.
Practice
Solution
Step 1: Understand middleware role
Middleware functions run one after another to handle requests or responses in a chain.Step 2: Understand decorator role
Decorators wrap a function to add or modify its behavior without changing the original function.Final Answer:
Middleware processes requests in a chain; decorators wrap functions to add behavior. -> Option DQuick Check:
Middleware = chain, Decorator = wrap [OK]
- Confusing middleware with decorators
- Thinking middleware wraps functions
- Assuming both are identical
Solution
Step 1: Recall Express middleware signature
Middleware functions take three parameters in order: request, response, and next function.Step 2: Check parameter order and usage
function middleware(req, res, next) { next(); } correctly uses (req, res, next) and calls next() to pass control.Final Answer:
function middleware(req, res, next) { next(); } -> Option AQuick Check:
Middleware signature = (req, res, next) [OK]
- Mixing parameter order
- Forgetting to call next()
- Returning next() instead of calling
function logDecorator(fn) {
return function(...args) {
console.log('Calling function');
return fn(...args);
};
}
function greet(name) {
return `Hello, ${name}!`;
}
const decoratedGreet = logDecorator(greet);
console.log(decoratedGreet('Alice'));What will be printed to the console?
Solution
Step 1: Understand decorator behavior
The decorator wraps greet, logging 'Calling function' before calling greet.Step 2: Trace function calls and output
Calling decoratedGreet('Alice') logs 'Calling function' then returns 'Hello, Alice!'. Both are printed by console.log.Final Answer:
Calling function\nHello, Alice! -> Option AQuick Check:
Decorator logs then calls function [OK]
- Assuming only greeting prints
- Confusing order of console logs
- Missing decorator wrapping effect
function logger(req, res, next) {
console.log('Request URL:', req.url);
next;
}What is the bug and how to fix it?
Solution
Step 1: Identify middleware flow control
Middleware must call next() as a function to continue the chain.Step 2: Spot the bug in next usage
Code uses next without parentheses, so next middleware is never called.Final Answer:
next is not called as a function; fix by changing to next() -> Option CQuick Check:
Call next() to continue middleware chain [OK]
- Writing next instead of next()
- Assuming req.url is invalid
- Thinking middleware must return a value
function fetchData(userId) {
return `Data for user ${userId}`;
}Solution
Step 1: Understand the goal
You want to add authentication without changing fetchData itself.Step 2: Choose the right pattern
Decorators wrap functions to add behavior like authentication without modifying original code.Final Answer:
Use a decorator to wrap fetchData and check authentication before calling it. -> Option BQuick Check:
Decorator = add behavior without changing function [OK]
- Confusing middleware with decorators
- Modifying original function directly
- Thinking middleware wraps functions
Ready to prove it?
Pass the test and this pattern moves unknown
