How to apply middleware to a specific router in express? - node.js

Below code is from http://expressjs.com/en/guide/using-middleware.html#middleware.router. It defines a middleware on express router instance. It works fine but if I define another router and that router will also use the same middleware. Can I define a middleware only for a particular express.Router() instance?
var app = express()
var router = express.Router()
// predicate the router with a check and bail out when needed
router.use(function (req, res, next) {
if (!req.headers['x-auth']) return next('router')
next()
})
router.get('/', function (req, res) {
res.send('hello, user!')
})
// use the router and 401 anything falling through
app.use('/admin', router, function (req, res) {
res.sendStatus(401)
})

To use something specific to a route you can use the .all() function
router.route('/')
.all(function (req, res, next){
// do middleware stuff here and call next
next();
})
.get(function (req, res) {
res.send('hello, user!');
});

Related

express - getting path of parrent router?

Lets say I want to have 2 different instances in "subfolders" in the url. In app js I have it defined like this:
var routes = require('./routes/index');
app.use('/myapp1', routes);
app.use('/myapp2', routes);
The inner routing would be the same.
But still in the router I want to "get" the path defined in the app.use - eg.: myapp1, myapp2
How do I get this in the router?
From routes/index.js:
router.use(/\/.*/, function (req, res, next) {
// want to see "myapp1/myapp2" without the *sub* path defined in this particular router eg.: /products /user etc.
next();
});
You might want to use the req.baseUrl property.
Example:
routes.get('/1', function(req, res) {
res.send([
req.baseUrl,
req.path,
req.baseUrl + req.path,
].join('\n'));
});
app.use('/api', routes);
Making an HTTP request to /api/1 would print:
/api
/1
/api/1
var express = require('express');
var app = express();
var router = express.Router();
app.use(function(req, res, next) {
req.appInstance = (req.url.indexOf('/app2/') == 0) ? 2 : 1;
next();
});
app.get('/', function(req, res, next) {
res.redirect('/app1/user');
});
router.get('/user', function(req, res, next) {
res.send(req.url +' on app' + req.appInstance);
});
app.use('/app1', router);
app.use('/app2', router);
app.listen(3000, function () {
console.log('Example app listening on port 3000!');
});

Trying to pass an object to an external route file using Nodejs and Expess

I have my nodeapp and an external route file.
I am trying to pass the object clientMap to the external router
When i try to pass using syntax from examples
app.use('/api', apiRoutes)(clientMap);
i always get the error
node_modules\express\lib\router\index.js:140 var search = 1 +
req.url.indexOf('?');
TypeError: Cannot call method 'indexOf' of undefined
at Function.handle
This is how i have it currently(just snippets cause this is a big app), which does not work
app.js
var app = express();
var http = require('http').Server(app);
var apiRoutes = require('./routes/apiRoutes');
app.use('/api', apiRoutes)(clientMap);
apiRoutes.js
module.exports = (function (clientMap) {
var router = express.Router();
router.use(function (req, res, next) {
});
router.get('/userlist', function (req, res, next) {
});
return router;
})();
I have also tried and get the same error
app.use('/api', apiRoutes(clientMap));
You should be passing to apiRoutes, not app.use:
app.use('/api', apiRoutes(clientMap));
You also want to be exporting a function as apiRoutes, not calling it as an IIFE:
module.exports = function (clientMap) {
var router = express.Router();
router.use(function (req, res, next) {
});
router.get('/userlist', function (req, res, next) {
});
return router;
};

NodeJS / ExpressJS check valid token parameter before routing

I have the following app code:
(app.js)
var express = require('express')
, app = express()
, port = process.env.PORT || 8082
app.use(require('./controllers'))
app.use(function(req, res, next) {
res.send('Test')
next()
})
app.listen(port, function() {
console.log('Listening on port ' + port)
})
and two controllers:
(index.js)
var express = require('express')
, router = express.Router()
router.use('/projects', require('./projects'))
module.exports = router
(projects.js)
var express = require('express')
, router = express.Router()
router.get('/:id', function(req, res, next) {
res.json({project: req.params.id})
})
module.exports = router
This works but now I have to check my url for a valid token.
My url looks like http://server/api/projects?token=abc or http://server/api/projects/:id?token=abc
If the token is not valid no projects (or other controllers) should be load / shown.
What is the best way to handle this and where (in app.js or controllers/index.js)?
Use a middleware.
app.use(function (req, res, next) {
if (checkToken(req.query.token) {
return next();
}
res.status(403).end("invalid token");
});
app.use(require('./controllers'))
You can do this validation inside your route function or you can use a middleware that validates the param and then do some logic.
var express = require('express')
, router = express.Router()
function validate(req,res,next) {
if(req.params.id) // some logic
else other stuff
next();
}
router.get('/:id', validate, function(req, res, next) {
res.json({project: req.params.id})
})
module.exports = router

Callback routes with expressjs

Please, i need to figure out why the external callback(defined in a diff file) assigned to a route like
app.get('/list', routes.list);
it's working and if I define
var router = express.Router();
router.get('/list', routes.list);
the callback stops to work.
Thanks.
You should apply routes for your application, for example
var routes = {
list: function (req, res, next) {
res.sendFile(path.join(__dirname, './public', 'index.html'));
}
};
// app.get('/list', routes.list);
router.get('/list', routes.list);
// apply the routes to our application
app.use('/', router);
app.listen(3000);

using Router in express-4

i am trying to execute below code after upgrading express4
// call the Router
var router = express.Router();
router.get('/test1', function(req, res, next) {
// doing more stuff
res.send('test test1 route')
});
// call our router we just created
app.use('/dogs', dogs);
but for some reason i am getting following error
this._router = new Router({
^
TypeError: object is not a function
at Function.app.lazyrouter
can someone help me to solve this problem ,Thank you in advance.
From the documentation:
var app = express();
app.route('/events')
.all(function(req, res, next) {
// runs for all HTTP verbs first
// think of it as route specific middleware!
})
.get(function(req, res, next) {
res.json(...);
})
.post(function(req, res, next) {
// maybe add a new event...
})
So try:
var router = app.route();
router.get('......
Or check the 3 to 4 upgrade guide.
Which says:
app.router has been removed and middleware and routes are executed in
the order they are added. Your code should move any calls to app.use
that came after app.use(app.router) after any routes (HTTP verbs).
app.use(cookieParser());
app.use(bodyParser());
/// .. other middleware .. doesn't matter what
app.get('/' ...);
app.post(...);
// more middleware (executes after routes)
app.use(function(req, res, next);
// error handling middleware
app.use(function(err, req, res, next) {});
I don't have a reputation to comment. Where and how did you declare your dog? Did you mean the following?:
// call the Router
var router = express.Router();
// call our router we just created
app.use(router);
router.get('/test1', function(req, res, next) {
// doing more stuff
res.send('test test1 route')
});
we can use this approach for routing in express4, when i am upgrading to express4 i didn't deleted express 3 folder, i tried deleting express3 folder from node modules and installing express4 than this worked fine

Resources