How do i send multiple arguments to an Express.js route? - node.js

Let say I want to add multiple arguments.
Here's the code
function firstArgument(req, res, next) {
// Do something
}
function secondArgument(req, res, next) {
// Do something
}
app.get('/something', firstArgument, secondArgument, function(req, res, next) {
// Is it possible to do this?
});
Is it possible? if so how does it works? Can anyone explain it to me.
Thank you

All the answers are in the express docs - http://expressjs.com/es/guide/routing.html
To summarize, for your scenario you can use:
var cb0 = function (req, res, next) {
console.log('CB0')
next()
}
var cb1 = function (req, res, next) {
console.log('CB1')
next()
}
app.get('/example/d', [cb0, cb1], function (req, res, next) {
console.log('response will be sent by the next function ...')
next()
}, function (req, res) {
res.send('Hello from D!')
})
or, without the second method.
var cb0 = function (req, res, next) {
console.log('CB0')
next()
}
var cb1 = function (req, res, next) {
console.log('CB1')
next()
}
app.get('/example/d', [cb0, cb1], function (req, res) {
res.send('Hello from D!')
})
Regarding how it works - it simply runs all the methods one after the other: when the next() method is called, the next method is being called.

Related

Is it possible to dynamically use a route part to call passport strategy?

Currently, I have the following code for many more oath provider:
// facebook
router.get("/facebook", passport.authenticate("facebook", { scope: ["email"] }));
router.get("/facebook/callback", passport.authenticate("facebook"), (req, res) => {
console.log(chalk.blue("went into facebook callback"));
res.redirect("http://localhost:3000/profile");
});
// github
router.get("/github", passport.authenticate("github"));
router.get("/github/callback", passport.authenticate("github"), (req, res) => {
console.log(chalk.blue("went into github callback"));
res.redirect("http://localhost:3000/profile");
});
Is there a way to unify that into an abstracted route? I.e. something like
// github
router.get("/:provider", passport.authenticate(:provider));
router.get("/:provider/callback", passport.authenticate(:provider), (req, res) => {
console.log(chalk.blue("went into {:provider} callback"));
res.redirect("http://localhost:3000/profile");
});
Update:
The following piece of code does what I want. Thx to #Usman Abdur Rehman.
function callbackDistributer(req, res, next) {
console.log(req.params);
global.provider = req.params.provider;
next();
}
router.get(
"/:provider/callback",
callbackDistributer,
(req, res, next) => {
passport.authenticate(global.provider)(req, res, next);
},
(req, res) => {
console.log(chalk.red("went into: " + global.provider));
res.redirect("http://localhost:3000/profile");
}
);
Have a middleware function going before the passport.authenticate middleware
function ownMiddleware(req,res,next){
global.provider = req.params.provider
next()
}
and then use it in the route handler as
router.get("/:provider/callback", ownMiddleware ,passport.authenticate(global.provider), (req, res) => {
console.log(chalk.blue("went into {:provider} callback"));
res.redirect("http://localhost:3000/profile");
});
I think it should work

how to group api in express

Here is the example:
var app = require('express')();
function validateToken(req, res, next) {
// Do something with request here
next();
};
app.get('/user/login', function(req, res) {
//code
});
app.post('/user/register', function(req, res) {
//code
})
app.put('/user/register', validateToken, function(req, res) {
//code
})
app.delete('/user/delete', validateToken, function(req, res) {
//code
})
If I have 10 api that need validToken, I should add validToken middleware 10 times, like:
app.method('......', validateToken, function(req, res) {
//code
})
app.method('......', validateToken, function(req, res) {
//code
})
....
app.method('......', validateToken, function(req, res) {
//code
})
app.method('......', validateToken, function(req, res) {
//code
})
How can I group api by using the same middleware?
Here's how to re-use the same callback function for multiple routes (like middleware):
var app = require('express')();
function validateToken(req, res, next) {
// Do something with request here
next();
};
app.get('/user/login', function(req, res) {
// code
});
app.post('/user/register', function(req, res) {
// code
});
// Be sure to specify the 'next' object when using more than one callback function.
app.put('/user/register', validateToken, function(req, res, next) {
// code
next();
});
app.delete('/user/delete', validateToken, function(req, res, next) {
// code
next();
});
Also, you can replace app.METHOD (e.g. .post, .get, .put, etc.) with app.all and your callback will be executed for any request type.
Just wrong, so do not put into mass participation of the (Google translated from: 刚才看错了,改成这样就不用放进传参了)
var group = {url:true,url:true,url:true};
app.use(function(req,res,next){
if(group[req.url]){
// Do something with request here
next();
} else {
next();
}
})

Express js routing with query string

I want to do something like this. I want to use different middleware if there is or isn't a certain query string.
app.get("/test?aaa=*", function (req, res) {
res.send("query string aaa found");
});
app.get("/test", middleware, function (req, res) {
res.send("no query string");
});
However, I failed. Can anyone help me? Thanks.
EDIT: I only need to add the middleware, I dont care what the value of the query string is
If your intention is to run the same route handler and call the middleware depending on whether the query string matches, you can use some sort of wrapping middleware:
var skipIfQuery = function(middleware) {
return function(req, res, next) {
if (req.query.aaa) return next();
return middleware(req, res, next);
};
};
app.get("/test", skipIfQuery(middleware), function (req, res) {
res.send(...);
});
If you want to have two route handlers, you could use this:
var matchQueryString = function(req, res, next) {
return next(req.query.aaa ? null : 'route');
};
app.get("/test", matchQueryString, function (req, res) {
res.send("query string aaa found");
});
app.get("/test", middleware, function (req, res) {
res.send("no query string");
});
(these obviously aren't very generic solutions, but it's just to give an idea on how to solve this)
You can do this:
app.get("/test", middleware, function (req, res) {
res.send("no query string");
});
middleware = function(req, res, next) {
if(!req.query.yourQuery) return next();
//middleware logic when query present
}

Express dynamic route's get added to static routes middleware stack

I am defining static & dynamic routes in Express, and I have built a generic responder to send response to client. The responder is global to all routes and thus added at the end.
However, when I define static routes, matching dynamic routes' middlewares get added to the stack before the responder.
To illustrate:
server.get('/hello/test', function(req, res, next) {
console.log('/hello/test');
next();
});
server.get('/hello/:page', function(req, res, next) {
console.log('/hello/:page');
next();
});
server.use(function(req, res, next) {
res.status(200).send('test');
});
Calling curl localhost:3000/hello/test will console.log both '/hello/test' and '/hello/:page' before the responder middleware gets called. I only want the first matching routes middleware to be called.
Is there anyway to prevent this behaviour?
The method next() is passing the control to the next handler.
You could solve your issue just removing the next() call from your routes, and putting the middleware into a function:
server.get('/hello/test', myMiddleware(req, res, next), function(req, res) {
console.log('/hello/test');
});
server.get('/hello/test_b', myMiddleware(req, res, next), function(req, res) {
console.log('/hello/test_b');
});
server.get('/hello/:page', myMiddleware(req, res, next), function(req, res) {
console.log('/hello/:page');
});
server.get('*', myMiddleware(req, res, next), function (req, res) {
res.type('txt').send('Not found');
});
function myMiddleware(req, res, next) {
console.Log("in midleware")
next();
}

Express.js multiple methods

So in Express you can do:
app.get('/logo/:version/:name', function (req, res, next) {
// Do something
}
and
app.all('/logo/:version/:name', function (req, res) {
// Do something
}
Is there a way to just have two methods (ie. GET and HEAD)? Such as:
app.get.head('/logo/:version/:name', function (req, res, next) {
// Do something
}
You can use .route() method.
function logo(req, res, next) {
// Do something
}
app.route('/logo/:version/:name').get(logo).head(logo);
Just pull out the anonymous function and give it a name:
function myRouteHandler(req, res, next) {
// Do something
}
app.get('/logo/:version/:name', myRouteHandler);
app.head('/logo/:version/:name', myRouteHandler);
Or use a general middleware function and check the req.method:
app.use('/logo/:version/:name', function(req, res, next) {
if (req.method === 'GET' || req.method === 'HEAD') {
// Do something
} else
next();
});
another version:
['get','head'].forEach(function(method){
app[method]('/logo/:version/:name', function (req, res, next) {
// Do something
});
});
You can also use the array spread operator if your route pattern is the same for multiple methods.
e.g.
const route = [
'/logo/:version/:name',
function handleRequest(req, res) {
// handle request
}
];
app.get(...route);
app.post(...route);

Resources