Bird
Raised Fist0
Expressframework~10 mins

Middleware factory pattern in Express - Step-by-Step Execution

Choose your learning style10 modes available
Concept Flow - Middleware factory pattern
Call factory function with config
↓
Factory returns middleware function
↓
Express uses middleware in request flow
↓
Middleware runs with access to config
↓
Next middleware or response
The factory function creates a middleware configured by input, which Express then runs during requests.
Execution Sample
Express
function logger(level) {
  return function(req, res, next) {
    console.log(`[${level}] ${req.method} ${req.url}`);
    next();
  };
}
app.use(logger('INFO'));
Creates a logger middleware with a level, logs request info, then calls next middleware.
Execution Table
StepActionInput/StateOutput/Result
1Call logger factory with 'INFO'level = 'INFO'Returns middleware function with level='INFO'
2Express receives request GET /homereq.method='GET', req.url='/home'Middleware function called with req, res, next
3Middleware logs messagelevel='INFO', req.method='GET', req.url='/home'Console logs: [INFO] GET /home
4Middleware calls next()next functionExpress continues to next middleware or route handler
5Request handled or response sentNo more middlewareResponse sent to client
💡 Middleware calls next(), allowing Express to continue request processing or send response.
Variable Tracker
VariableStartAfter Step 1After Step 2After Step 3Final
levelundefined'INFO''INFO''INFO''INFO'
middleware functionundefinedfunction(req,res,next)function(req,res,next)function(req,res,next)function(req,res,next)
req.methodundefinedundefined'GET''GET''GET'
req.urlundefinedundefined'/home''/home''/home'
Key Moments - 2 Insights
Why does the factory function return another function instead of doing the work immediately?
The factory returns a middleware function so Express can call it later with request info. See step 1 and 2 in execution_table where the factory returns a function, and Express calls it with req, res, next.
What happens if the middleware does not call next()?
Express will stop processing further middleware or routes, causing the request to hang. Step 4 shows calling next() lets Express continue.
Visual Quiz - 3 Questions
Test your understanding
Look at the execution_table, what is logged to the console at step 3?
A[ERROR] GET /home
B[INFO] GET /home
C[INFO] POST /home
D[DEBUG] GET /home
💡 Hint
Check the 'Output/Result' column in step 3 of execution_table.
At which step does Express call the middleware function returned by the factory?
AStep 4
BStep 1
CStep 2
DStep 5
💡 Hint
Look at the 'Action' column describing when middleware is called.
If the factory was called with 'ERROR' instead of 'INFO', what would change in the execution_table?
AThe logged message at step 3 would show [ERROR] instead of [INFO]
BThe middleware would not be called
CThe request method would change
DNothing would change
💡 Hint
Refer to the 'Input/State' and 'Output/Result' columns at step 3.
Concept Snapshot
Middleware factory pattern:
- A function that takes config and returns middleware
- Middleware runs later with req, res, next
- Allows customizing middleware behavior
- Must call next() to continue Express flow
- Example: logger(level) returns middleware logging requests
Full Transcript
The middleware factory pattern in Express means writing a function that takes some settings and returns a middleware function. This returned middleware runs when Express handles a request. For example, a logger factory takes a level like 'INFO' and returns a middleware that logs each request with that level. When a request comes in, Express calls the middleware with request and response objects. The middleware logs the message and calls next() to let Express continue. This pattern helps customize middleware behavior easily. Key points: the factory returns a function, middleware runs later, and next() must be called to avoid stopping the request.

Practice

(1/5)
1. What is the main purpose of the middleware factory pattern in Express?
easy
A. To automatically handle errors in middleware
B. To create middleware functions that can be customized with different settings
C. To replace the need for routing in Express
D. To speed up server response time by caching

Solution

  1. Step 1: Understand middleware factory pattern concept

    The middleware factory pattern is used to create middleware functions that accept parameters to customize their behavior.
  2. 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.
  3. Final Answer:

    To create middleware functions that can be customized with different settings -> Option B
  4. Quick Check:

    Middleware factory pattern = customizable middleware [OK]
Hint: Middleware factory = function returning middleware with parameters [OK]
Common Mistakes:
  • Thinking it automatically handles errors
  • Confusing with routing or caching
  • Believing it speeds response time directly
2. Which of the following is the correct syntax for a middleware factory function in Express?
easy
A. function logger() { /* middleware code */ }
B. function logger(req, res, next) { return function(level) { /* middleware code */ } }
C. function logger(level) { return function(req, res, next) { /* middleware code */ } }
D. function logger(level, req, res, next) { /* middleware code */ }

Solution

  1. 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).
  2. 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.
  3. Final Answer:

    function logger(level) { return function(req, res, next) { /* middleware code */ } } -> Option C
  4. Quick Check:

    Factory returns middleware function = function logger(level) { return function(req, res, next) { /* middleware code */ } } [OK]
Hint: Factory takes params, returns (req, res, next) function [OK]
Common Mistakes:
  • Placing req, res, next in factory parameters
  • Not returning a middleware function
  • Confusing middleware and factory signatures
3. Given the middleware factory below, what will be logged when a request is made?
function greet(name) {
  return function(req, res, next) {
    console.log(`Hello, ${name}!`);
    next();
  };
}

app.use(greet('Alice'));
medium
A. Hello, Alice!
B. Hello, undefined!
C. Hello, name!
D. No output, middleware does not log

Solution

  1. Step 1: Understand middleware factory usage

    The factory greet('Alice') returns a middleware that logs 'Hello, Alice!'.
  2. Step 2: Predict middleware behavior on request

    When a request comes, the middleware logs the greeting with the name 'Alice'.
  3. Final Answer:

    Hello, Alice! -> Option A
  4. Quick Check:

    Factory param used in log = Hello, Alice! [OK]
Hint: Factory param appears in log output [OK]
Common Mistakes:
  • Expecting 'undefined' if factory param missing
  • Thinking middleware does not log
  • Confusing variable name with string literal
4. Identify the error in this middleware factory code:
function checkRole(role) {
  return function(req, res, next) {
    if(req.user.role === role) {
      next;
    } else {
      res.status(403).send('Forbidden');
    }
  };
}
medium
A. res.status should be res.send
B. Incorrect comparison operator in if statement
C. Middleware factory should not return a function
D. Missing parentheses when calling next()

Solution

  1. Step 1: Review middleware function call

    Inside middleware, next must be called as a function: next().
  2. Step 2: Identify the error

    The code uses 'next;' instead of 'next();', so middleware will not proceed correctly.
  3. Final Answer:

    Missing parentheses when calling next() -> Option D
  4. Quick Check:

    Call next() with parentheses [OK]
Hint: Always call next() as a function, not just next [OK]
Common Mistakes:
  • Writing next without parentheses
  • Confusing status and send methods
  • Thinking factory should not return a function
5. You want to create a middleware factory that limits requests based on a max count per user. Which approach correctly applies the middleware factory pattern to achieve this?
hard
A. 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(); } }; }
B. function rateLimiter(req, res, next, maxRequests) { // logic here }
C. function rateLimiter(maxRequests) { return function(req, res) { // missing next call }; }
D. function rateLimiter() { // no parameters, fixed limit }

Solution

  1. Step 1: Understand the requirement for customizable limit

    The middleware must accept maxRequests as a parameter to customize the limit.
  2. 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.
  3. 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 A
  4. Quick 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]
Hint: Factory takes limit param, returns middleware calling next() [OK]
Common Mistakes:
  • Putting next as a factory parameter
  • Not calling next() in middleware
  • Not using maxRequests parameter
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard