Discover how one simple function can save you from endless middleware copy-pasting!
Why Middleware factory pattern in Express? - Purpose & Use Cases
Imagine you need to create several similar middleware functions in Express, each with slightly different settings, like logging different messages or checking different user roles.
You write each middleware by hand, copying and changing code for every variation.
This manual approach leads to repeated code, making your app harder to maintain and prone to mistakes.
Every time you want a new variation, you must copy, paste, and carefully edit, risking bugs and wasted time.
The middleware factory pattern lets you write one function that creates customized middleware based on parameters you give it.
This means you write less code, avoid repetition, and can easily create many middleware variations by just calling the factory with different options.
function logAdmin(req, res, next) { console.log('Admin access'); next(); } function logUser(req, res, next) { console.log('User access'); next(); }function createLogger(role) { return function(req, res, next) { console.log(`${role} access`); next(); } } const logAdmin = createLogger('Admin'); const logUser = createLogger('User');This pattern enables flexible, reusable middleware that adapts easily to different needs without rewriting code.
In a web app, you can create one middleware factory to check user roles, then generate middleware for 'admin', 'editor', or 'viewer' roles simply by passing the role name.
Manual middleware duplication wastes time and risks errors.
Middleware factory pattern creates customizable middleware with one function.
It improves code reuse, clarity, and maintenance.
Practice
middleware factory pattern in Express?Solution
Step 1: Understand middleware factory pattern concept
The middleware factory pattern is used to create middleware functions that accept parameters to customize their behavior.Step 2: Compare options with the concept
Only To create middleware functions that can be customized with different settings correctly describes creating customizable middleware functions. Other options describe unrelated features.Final Answer:
To create middleware functions that can be customized with different settings -> Option BQuick Check:
Middleware factory pattern = customizable middleware [OK]
- Thinking it automatically handles errors
- Confusing with routing or caching
- Believing it speeds response time directly
Solution
Step 1: Identify middleware factory structure
A middleware factory is a function that takes parameters and returns a middleware function with signature (req, res, next).Step 2: Match syntax to this pattern
function logger(level) { return function(req, res, next) { /* middleware code */ } } matches this: it takes 'level' and returns a function with (req, res, next). Others do not follow this pattern.Final Answer:
function logger(level) { return function(req, res, next) { /* middleware code */ } } -> Option CQuick Check:
Factory returns middleware function = function logger(level) { return function(req, res, next) { /* middleware code */ } } [OK]
- Placing req, res, next in factory parameters
- Not returning a middleware function
- Confusing middleware and factory signatures
function greet(name) {
return function(req, res, next) {
console.log(`Hello, ${name}!`);
next();
};
}
app.use(greet('Alice'));Solution
Step 1: Understand middleware factory usage
The factory greet('Alice') returns a middleware that logs 'Hello, Alice!'.Step 2: Predict middleware behavior on request
When a request comes, the middleware logs the greeting with the name 'Alice'.Final Answer:
Hello, Alice! -> Option AQuick Check:
Factory param used in log = Hello, Alice! [OK]
- Expecting 'undefined' if factory param missing
- Thinking middleware does not log
- Confusing variable name with string literal
function checkRole(role) {
return function(req, res, next) {
if(req.user.role === role) {
next;
} else {
res.status(403).send('Forbidden');
}
};
}Solution
Step 1: Review middleware function call
Inside middleware, next must be called as a function: next().Step 2: Identify the error
The code uses 'next;' instead of 'next();', so middleware will not proceed correctly.Final Answer:
Missing parentheses when calling next() -> Option DQuick Check:
Call next() with parentheses [OK]
- Writing next without parentheses
- Confusing status and send methods
- Thinking factory should not return a function
Solution
Step 1: Understand the requirement for customizable limit
The middleware must accept maxRequests as a parameter to customize the limit.Step 2: Check which option correctly returns middleware with (req, res, next) and uses maxRequests
function rateLimiter(maxRequests) { const counts = new Map(); return function(req, res, next) { const user = req.user.id; counts.set(user, (counts.get(user) || 0) + 1); if(counts.get(user) > maxRequests) { res.status(429).send('Too many requests'); } else { next(); } }; } correctly implements a factory that returns middleware tracking counts and enforcing maxRequests, calling next() properly.Final Answer:
function rateLimiter(maxRequests) { const counts = new Map(); return function(req, res, next) { const user = req.user.id; counts.set(user, (counts.get(user) || 0) + 1); if(counts.get(user) > maxRequests) { res.status(429).send('Too many requests'); } else { next(); } }; } -> Option AQuick Check:
Factory with param returns middleware calling next() = function rateLimiter(maxRequests) { const counts = new Map(); return function(req, res, next) { const user = req.user.id; counts.set(user, (counts.get(user) || 0) + 1); if(counts.get(user) > maxRequests) { res.status(429).send('Too many requests'); } else { next(); } }; } [OK]
- Putting next as a factory parameter
- Not calling next() in middleware
- Not using maxRequests parameter
Ready to prove it?
Pass the test and this pattern moves unknown
