Reputation: 37121
I have an app like this:
import express from 'express';
const middleware = tag => (req, res, next) => {
console.log('middleware ' + tag);
next();
};
const app = express();
const router = express.Router();
router.use(middleware('a'));
router.get('/x', (req, res) => res.json({ message: 'x' }));
app.use(router);
app.use(middleware('b'));
app.get('/y', (req, res) => res.json({ message: 'y' }));
app.use(middleware('c'));
app.listen(3000);
However, Router
does not behave as I expected:
$ curl localhost:3000/x
middleware a
$ curl localhost:3000/y
middleware a
middleware b
Why does hitting /y
call the middleware? I thought that the middleware was only applied to router
.
How can I apply a middleware to only router
, and not the other routes in app
?
Upvotes: 2
Views: 142
Reputation: 2693
When you do
app.use(router);
you mount the router at the root /
path of your app. The router's middleware
router.use(middleware('a'));
is mounted at the root path or the router, and so at the root path of the app. Middleware mounted at the root path is executed for every request.
How can I apply a middleware to only router, and not the other routes in app?
You can mount the router at /x
and make the router handle /
its root path:
router.get('/', (req, res) => res.json({ message: 'x' }));
app.use('/x', router);
Upvotes: 1
Reputation: 4174
Even if you've done it via a router, because you then attached the router with no sub-path it bundled everything together. In your example you have attached everything to the same parent endpoint /
, so even though it's done via a router you are then attaching this router to the /
path.
If you want to just separate middleware out as you've indicated then you have two options.
Sub-path the endpoints to something like /feature1/x
and /feature2/y
. Attach the middleware to the /feature1
and /feature2
respectively. This will give you the desired outcome. This could be done by attaching your router for endpoint /x
in this way:
app.use('/feature1', router);
Which would mean you now have the endpoints /feature1/x
and /y
. Each triggering it's independent chain of middleware.
Attach the middleware to the specific endpoint such as:
app.get('/x, middleware('a'), (req, res) => res.json({message: 'x'});
app.get('/y', middleware('b'), (req, res) => res.json({message: 'y'});
What you've done at the moment is attach everything to the same route path (in this case the top level slash /
).
Upvotes: 2