What if you could protect whole sections of your app with just one simple step?
Why Router level middleware in Express? - Purpose & Use Cases
Imagine building a web app where you want to check user login status only for certain parts of your site, like the admin pages, but not for the public pages.
You try to add the same login check code inside every route handler manually.
Manually adding the same check in every route is tiring and easy to forget.
If you miss one, unauthorized users might sneak in.
Also, updating the check means changing many places, which is slow and error-prone.
Router-level middleware lets you attach a function that runs automatically for all routes in a specific router.
This means you write the login check once, and it applies only where you want.
It keeps your code clean, safe, and easy to update.
app.get('/admin/dashboard', checkLogin, (req, res) => { ... }); app.get('/admin/settings', checkLogin, (req, res) => { ... });
const adminRouter = express.Router(); adminRouter.use(checkLogin); adminRouter.get('/dashboard', (req, res) => { ... }); adminRouter.get('/settings', (req, res) => { ... }); app.use('/admin', adminRouter);
You can organize your app so middleware runs only where needed, making your code safer and easier to manage.
In an online store, you want to verify admin users before they access product management pages, but let shoppers browse products freely.
Router-level middleware lets you protect admin routes without affecting public pages.
Manually repeating middleware code is error-prone and hard to maintain.
Router-level middleware runs middleware functions for all routes in a router automatically.
This keeps your app organized, secure, and easier to update.
Practice
Solution
Step 1: Understand router-level middleware scope
Router-level middleware runs only for routes defined in that router, not the entire app.Step 2: Compare with other middleware types
Main app middleware runs for all routes, error middleware handles errors, static middleware serves files. Router middleware is specific to router routes.Final Answer:
To run middleware only for routes defined in a specific router -> Option BQuick Check:
Router middleware scope = specific router routes [OK]
- Confusing router middleware with app-level middleware
- Thinking router middleware handles errors globally
- Assuming router middleware serves static files
Solution
Step 1: Recall Express router middleware syntax
The correct method to add middleware to a router isrouter.use().Step 2: Check other options for validity
router.middleware,app.useRouter, androuter.addare not valid Express methods.Final Answer:
router.use(function(req, res, next) { next(); }); -> Option DQuick Check:
Use router.use() to add middleware [OK]
- Using non-existent methods like router.middleware or router.add
- Confusing app.useRouter with router.use
- Forgetting to call next() inside middleware
const express = require('express');
const router = express.Router();
router.use((req, res, next) => {
console.log('Middleware A');
next();
});
router.get('/test', (req, res) => {
res.send('Hello from test');
});
module.exports = router;What will be printed in the console when a client requests
/test on this router?Solution
Step 1: Identify middleware behavior on route request
The router middleware logs 'Middleware A' and calls next(), so it runs before the route handler.Step 2: Understand console output vs response
The console.log prints 'Middleware A' to the server console. The response sends 'Hello from test' to the client but does not print to console.Final Answer:
Middleware A -> Option AQuick Check:
Middleware console.log prints 'Middleware A' [OK]
- Confusing console output with response content
- Expecting both console and response text in console
- Ignoring the next() call in middleware
const router = require('express').Router();
router.use((req, res, next) => {
console.log('First middleware');
next();
});
router.get('/hello', (req, res) => {
res.send('Hello World');
});
router.use((req, res) => {
});What is the problem with this code?
Solution
Step 1: Analyze middleware execution order
Middleware and routes execute in the order defined. First middleware runs for all requests and calls next().Step 2: Trace unmatched route behavior
For unmatched routes like /foo: first middleware calls next(), /hello route doesn't match so next(), last middleware runs but does nothing--no response and no next() call.Step 3: Identify the consequence
The request pipeline stops without a response, causing the client request to hang indefinitely.Final Answer:
The last middleware does not call next(), causing requests to hang -> Option AQuick Check:
No response + no next() = request hangs [OK]
- Thinking empty catch-all middleware is harmless
- Forgetting unmatched routes reach the last middleware
- Assuming the router automatically handles 404s
/api in your Express app. You create a router and add middleware like this:const express = require('express');
const app = express();
const apiRouter = express.Router();
apiRouter.use((req, res, next) => {
console.log('API request:', req.method, req.url);
next();
});
apiRouter.get('/users', (req, res) => {
res.send('User list');
});
app.use('/api', apiRouter);
app.get('/', (req, res) => {
res.send('Home');
});What will happen when a client requests
/api/users and /?Solution
Step 1: Understand router mounting path
The router is mounted at '/api', so its middleware runs only for routes starting with '/api'.Step 2: Analyze requests
Request to '/api/users' triggers the router middleware and route handler. Request to '/' goes directly to app.get('/') and skips router middleware.Final Answer:
Logging middleware runs only for /api/users, not for / -> Option CQuick Check:
Router middleware runs only on mounted path routes [OK]
- Assuming router middleware runs for all app routes
- Confusing app-level and router-level middleware scopes
- Expecting middleware to run for '/' when mounted on '/api'
Ready to prove it?
Pass the test and this pattern moves unknown
