📖 Scenario: You are building a simple Express server that uses middleware functions to process requests step-by-step. Middleware functions help you handle tasks like logging, authentication, and sending responses in a clear order.
🎯 Goal: Create an Express app with three middleware functions that run in sequence. Each middleware should log a message and call next() to pass control to the next middleware. The last middleware sends a response to the client.
📋 What You'll Learn
Create an Express app instance called app
Add a middleware function called logger that logs 'Logger middleware' and calls next()
Add a middleware function called auth that logs 'Auth middleware' and calls next()
Add a middleware function called finalHandler that logs 'Final handler' and sends 'Hello from Express!' as the response
Use app.use() to add the middleware functions in the order: logger, auth, finalHandler
Start the server on port 3000
💡 Why This Matters
🌍 Real World
Middleware is used in real web servers to handle logging, authentication, data parsing, and more in a clean, organized way.
💼 Career
Understanding middleware flow is essential for backend developers working with Express or similar web frameworks to build scalable and maintainable web applications.
Progress0 / 4 steps
1
Create Express app instance
Write code to import Express and create an app instance called app using express().
Express
Hint
Use require('express') to import Express and then call express() to create the app.
2
Add logger middleware
Create a middleware function called logger that takes req, res, and next as parameters. Inside it, log 'Logger middleware' and call next().
Express
Hint
Middleware functions always have three parameters: req, res, and next. Call next() to continue.
3
Add auth and finalHandler middleware and use them
Create two middleware functions: auth that logs 'Auth middleware' and calls next(), and finalHandler that logs 'Final handler' and sends 'Hello from Express!' as the response using res.send(). Then add all three middleware to app using app.use() in this order: logger, auth, finalHandler.
Express
Hint
Remember to call next() in auth to continue. The last middleware sends the response and does not call next().
4
Start the Express server
Add code to start the Express server on port 3000 using app.listen(). Inside the listen callback, log 'Server running on port 3000'.
Express
Hint
Use app.listen(3000, () => { ... }) to start the server and log a message inside the callback.
Practice
(1/5)
1. What does the next() function do in Express middleware?
easy
A. It passes control to the next middleware or route handler.
B. It sends the response back to the client immediately.
C. It stops the middleware chain and ends the request.
D. It modifies the request object permanently.
Solution
Step 1: Understand middleware flow
Middleware functions receive req, res, and next. Calling next() tells Express to continue to the next middleware or route.
Step 2: Identify the role of next()
Calling next() does not send a response or stop the chain; it moves control forward.
Final Answer:
It passes control to the next middleware or route handler. -> Option A
Quick Check:
next() = pass control [OK]
Hint: Remember: next() moves to the next step in middleware [OK]
Common Mistakes:
Thinking next() sends a response
Assuming next() stops middleware chain
Confusing next() with modifying req or res
2. Which of the following is the correct way to define middleware in Express?
easy
A. app.use((req, res, next) => { next(); });
B. app.use((req, res) => { next(); });
C. app.use((req, res, next) => { res.next(); });
D. app.use((req, res, next) => { next; });
Solution
Step 1: Check middleware function signature
Express middleware must have three parameters: req, res, and next.
Step 2: Verify correct usage of next()
Calling next() as a function is required to pass control. app.use((req, res, next) => { next(); }); correctly uses next() with all parameters.
Final Answer:
app.use((req, res, next) => { next(); }); -> Option A
A. The second middleware is missing next parameter.
B. console.log() causes an error in middleware.
C. res.send() cannot be called in middleware.
D. The first middleware never calls next(), so request hangs.
Solution
Step 1: Check middleware flow control
The first middleware logs 'Start' but does not call next() or send a response, so Express waits indefinitely.
Step 2: Understand consequence of missing next()
Without calling next(), the second middleware never runs, and the client gets no response.
Final Answer:
The first middleware never calls next(), so request hangs. -> Option D
Quick Check:
Missing next() causes hang [OK]
Hint: Always call next() or send response to avoid hanging [OK]
Common Mistakes:
Ignoring missing next() causes no response
Thinking console.log() breaks middleware
Assuming res.send() is invalid in middleware
5. You want to create middleware that logs request method and URL, then passes control only if the method is GET. Otherwise, it should send a 405 status. Which code correctly implements this?
hard
A. app.use((req, res, next) => {
console.log(req.method, req.url);
next();
res.status(405).send('Method Not Allowed');
});
B. app.use((req, res, next) => {
console.log(req.method, req.url);
if (req.method === 'GET') res.send('OK');
else next();
});
C. app.use((req, res, next) => {
console.log(req.method, req.url);
if (req.method === 'GET') next();
else res.status(405).send('Method Not Allowed');
});
D. app.use((req, res) => {
console.log(req.method, req.url);
if (req.method !== 'GET') next();
else res.status(405).send('Method Not Allowed');
});
Solution
Step 1: Log method and URL
The middleware logs req.method and req.url correctly in all options.
Step 2: Control flow based on method
app.use((req, res, next) => {
console.log(req.method, req.url);
if (req.method === 'GET') next();
else res.status(405).send('Method Not Allowed');
}); calls next() only if method is GET, else sends 405 status. This matches the requirement.
Step 3: Identify incorrect options
app.use((req, res, next) => {
console.log(req.method, req.url);
if (req.method === 'GET') res.send('OK');
else next();
}); sends 'OK' on GET instead of passing control. app.use((req, res, next) => {
console.log(req.method, req.url);
next();
res.status(405).send('Method Not Allowed');
}); calls next() then tries to send response (invalid). app.use((req, res) => {
console.log(req.method, req.url);
if (req.method !== 'GET') next();
else res.status(405).send('Method Not Allowed');
}); lacks next parameter and reverses logic.
Final Answer:
app.use((req, res, next) => {
console.log(req.method, req.url);
if (req.method === 'GET') next();
else res.status(405).send('Method Not Allowed');
}); -> Option C
Quick Check:
next() only on GET, else 405 = app.use((req, res, next) => {
console.log(req.method, req.url);
if (req.method === 'GET') next();
else res.status(405).send('Method Not Allowed');
}); [OK]
Hint: Call next() only for GET; send 405 otherwise [OK]
Common Mistakes:
Calling next() then sending response
Swapping condition logic
Missing next parameter in middleware
Recommended
Ready to prove it?
Pass the test and this pattern moves unknownstrongwhile earning +1 Grip toward your certificate.