in express how multiple callback works in app.get - node.js

I am newbie in node so please forgive me if i am not getting obvious.
In node.js express application for app.get function we typically pass route and view as parameters
e.g.
app.get('/users', user.list);
but in passport-google example I found that they are calling it as
app.get('/users', ensureAuthenticated, user.list);
where ensureAuthenticated is a function
function ensureAuthenticated(req, res, next) {
if (req.isAuthenticated()) { return next(); }
res.redirect('/login')
}
In short this means there are multiple callbacks which while running are called in series. i tried adding couple of more functions to make it look like
app.get('/users', ensureAuthenticated, dummy1, dummy2, user.list);
and i found ensureAuthenticated, dummy1, dummy2, user.list is getting called in series.
for my specific requirement i find calling functions sequentially in above form is quite elegant solution rather that using async series. can somebody explain me how it really works and how i can implement similar functionality in general.

In Express, each argument after the path is called in sequence. Usually, this is a way of implementing middleware (as you can see in the example you provided).
app.get('/users', middleware1, middleware2, middleware3, processRequest);
function middleware1(req, res, next){
// perform middleware function e.g. check if user is authenticated
next(); // move on to the next middleware
// or
next(err); // trigger error handler, usually to serve error page e.g. 403, 501 etc
}

Related

Koa2: how to write chain of middleware?

So in express, we can have a chain of middleware, copies an example:
middleware = function(req, res){
res.send('GET request to homepage');
});
app.get('/', middleware, function (req, res) {
res.send('GET request to homepage');
});
What's the equivalent way to write this in koa2 please ?
I'm thinking of using it for the route, for each route i want to have a middleware to check if user is already logged in.
Thanks !
If you're simply interested in making sure a middlware runs for every route, all you have to do is register the middleware before you register your routing middelware.
app.use(middleware);
As long as you call this before you 'use' your router, it will be called for every request. Just make sure you call the next function. This is how your middleware might look like:
function middleware(ctx, next) {
// Authenticate user
// Eventually call this
return next();
}

Order of route precedence express 3 vs 4

Accord to a book for express3. In the following case, http://localhost:3000/abcd will always print "abc*", even though the next route also matches the pattern.
My question is work in the same way for express4 ?
app.get('/abcd', function(req, res) {
res.send('abcd');
});
app.get('/abc*', function(req, res) {
res.send('abc*');
});
Reversing the order will make it print "abc*":
app.get('/abc*', function(req, res) {
res.send('abc*');
});
app.get('/abcd', function(req, res) {
res.send('abcd');
});
The first route handler that matches the route is the one that gets called. That's how Express works in all recent versions. You should generally specify your routes from more specific to less specific and then the more specific will match first and the less specific will catch the rest.
If you want a handler to see all matches and then pass things on to other handlers, you would generally use middleware:
// middleware
app.use("/abc*", function(req, res, next) {
// process request here and either send response or call next()
// to continue processing with other handlers that also match
next();
});

expressjs route methods before and after

How to add middleware functions to each of expressjs route functions ? Most of route functions which turn out to be CRUD on database have standard before and after statements - is there a way to have before and after for route functions.
app.route('/api/resources').all(projectsPolicy.isAllowed)
.get(resources.list)
.post(resources.create);
I think it's possible to make this:
app.route('/api/resources').all(projectsPolicy.isAllowed)
.get(before,resources.list,after)
.post(before,resources.create,after);
where before and after are functions
Express supports multiple callbacks, as in
app.get('/example/b', function (req, res, next) {
// do something here, like modify req or res, and then go on
next();
}, function (req, res) {
// get modified values here
});
which could also be written as
app.route('/api/resources', projectsPolicy.isAllowed).get(...
assuming the middlewares isAllowed() function calls next() etc.

Is there any way to monitor every response in Express.js?

I want to create a middleware function in express.js. which can monitor every requests and responses. I created a middleware but it can only monitor the requests, not the responses.
function middlewareFunc (req,res,next) {
console.log(req.body , req.params , req.query);
next();
}
You should know that res in function(req, res, next) is a instance of class http.ServerResponse. So it can be listen on finish event, please see the link: https://nodejs.org/api/stream.html#stream_event_finish
app.use(function (req, res, next) {
function afterResponse() {
res.removeListener('finish', afterRequest);
res.removeListener('close', afterRequest);
// action after response
}
res.on('finish', afterResponse);
res.on('close', afterResponse);
// action before request
// eventually calling `next()`
});
app.use(app.router);
app.use() and middleware can be used for "before" and a combination of the close and finish events can be used for "after."
For that you can write two middlewares
1) Before all request endpoints.
//middleware
function middlewareFunEarlier(req,res,next) {
console.log(req.body , req.params , req.query);
next();
}
app.use(middlewareFunEarlier);
app.get('/', function(req, res, next){
//do something
res.end();
});
2) After all end points. And you must have to use next() in all endpoints
app.get('/', function(req, res, next){
//do something
next();
});
app.use(middlewareFunLater);
//middlware
function middlewareFunLater(req, res, next){
console.log(res);
res.end();
}
It can be work around with existing tools.
Ok, so first of all, the reason you are only seeing the requests is because of how middleware works. Everything gets run once in a certain order, and runs only once. When your middleware gets run it is most likely before the response has been created. In order to get the response you would have to make your code run when your controller goes to render or something like that.
Second of all, it seems like basic logging is all you need.(weather it be with a library or just console logging stuff.)

Routes file issues with Passport

I'm using NodeJS, Express, and PassportJS to build a web application. I'm having a problem with one of my routes which I can't make any sense out of. When I have:
...
app.get('/auth/facebook', passport.authenticate('facebook'));
...
Everything seems to work fine. But when I change that to:
...
app.get('/auth/facebook',
function(req, res) {
passport.authenticate('facebook');
});
...
It hangs? Am I missing something on the app.get function? I want to be able to do this because I want to make the path a little more dynamic where I determine what passport authenticates. For example:
...
app.get('/auth/:provider',
function(req, res) {
passport.authenticate(req.params.provider);
});
...
Where provider could be facebook, twitter, or google...
passport.authenticate is middleware, take a gander at the source: https://github.com/jaredhanson/passport/blob/master/lib/passport/middleware/authenticate.js
passport.authenticate('facebook') returns a function that takes the req, res, next parameters from express and handles them.
so:
app.get('/auth/:provider',
function(req, res, next) {
passport.authenticate(req.params.provider)(req, res, next);
});
is what you need.

Resources