I am writing a nodejs application.
I want to to route all the requests to some common API. For that I am using
app.get('*', function(req, res) {
/* Do Something */
});
In "Do Something" Section I want to retrive the req.route.regexp and then based on that I will do processing. I am expecting req.route.regexp should be the exact URL's regexp for which we came here. But as I am handling this in '*', so regular expression is not giving me equivalent req.route.params.
So is there any way to get the regexp based on req.route.params in app.get of all routes (*).
Ex: I have url as: "/:val", for that I am expecting regexp
"/^/(?:([^/]+?))/?$/i", but I am getting regexp for "*",
so how I can achieve this?
When the handler of app.get('*', ...) is called, the eventual route hasn't been matched yet and express cannot possibly tell you about a subsequent route.
The only solution that I see would be to manually call a handler in all your routes:
app.get('/:val', function (req, res) {
if(!myGlobalHandler(req, res))
return;
});
function myGlobalHandler(req, res) {
if(somethingWrong(req)) {
res.send({error: 'uh oh...'});
return false;
}
return true;
}
If you tell me more about your use-case, maybe there's a more elegant solution.
Related
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();
});
I would like to use a middleware for checking users credentials only for some routes (those that start with /user/), but to my surprise server.use does not take a route as first argument and with restify-namespace server.use effect is still global.
Is there other way better than passing my auth middleware to all routes alongside the controller?
I think I'm going to just use server.use and inside the middleware make the following route check:
if (req.url.indexOf('/user/') !== 0) {
return next();
}
Unfortunately restify doesn't seem to be like express, which support the * operator. Hence, What I would suggest is grouping the routes that you desire together and apply a .use before them.
That is:
server.get('/test', function(req, res, next) {
// no magic here. server.use hasn't been called yet.
});
server.use(function(req, res, next) {
// do your magic here
if(some condition) {
// magic worked!
next(); // call to move on to the next middleware.
} else {
// crap magic failed return error perhaps?
next(new Error('some error')); // to let the error handler handle it.
}
});
server.get('/admin/', function(req, res, next) {
// magic has to be performed prior to getting here!
});
server.get('/admin/users', function(req, res, next) {
// magic has to be performed prior to getting here!
});
However, I would personally advocate the use of express, but choose whatever fits your need.
I am mimicking another api. I would also like to provide a different (better IMHO) api as well.
// this is url I need to support
api.post('/books/updateBook', function(req, res) {
...
});
// Would also like to support
api.put('/books/:bookId', function(req, res) {
...
});
I could easily do:
var updateBook = function(req, res) {
...
}
// this is url I need to support
api.post('/books/updateBook', updateBook);
// Would also like to support
api.put('/books/:bookId', updateBook);
Perfectly acceptable right? Being new to express I am wondering if there is a more 'express' way to handle this. I know you can use regex, but I am not sure you can map regex across different HTTP verbs (POST vs PUT).
Thoughts?
api.all('/books/:bookId', function (req, res, next) {
if (req.method === 'PUT' || req.method === 'POST) {
//get your groove on
} else {
next();
}
});
You can combine verbs in express, you just use all and examine the method, if it matches, handle the request other wise pass it down the handler chain (with next();).
That being said I think you're doing it right, there's no reason route handlers need to be lamdas.
I am looking to drive behavior through integration tests on an Express.js middleware. I have encountered an interesting circumstance where the behavior of Express behind the application is not predictable (not by me, anyway).
As a simplified example:
var middlewareExample = function(req, res, next){
if(req.session){
refreshSession(req.session, function(err, data){
if(!err){
res.redirect('/error');
}
});
next();
}else{
res.redirect('/authenticate');
}
};
The issue is the call to next following the redirect, as it lives outside of the inner function and conditional. I am not certain how Express handles middleware/route calls to next or res.redirect if they happen to take place before or after one another as seen above.
Manual testing has not revealed any strange behavior, nor has the supertest module. I would like to know if and how Express responds to circumstances such as this. Also, can supertest can be used to expose any potential unwanted behavior. Additionally, if I may, I would like to hear what approaches others would use to test Node/Express middleware in general.
you are sending two responses in the same request. next() is a response, assuming the next handler has a response as well, and so is res.redirect(). What you really want is:
var middlewareExample = function(req, res, next){
if(req.session){
refreshSession(req.session, next);
}else{
res.redirect('/authenticate');
}
};
I was experiencing this issue with the below example.
const redirect = () => (res, resp, next) => {
if (/* redirect condition met */) {
return resp.status(302).redirect(`https://example.com/${path_logic()}`);
} else {
return next();
}
}
app.use(redirect());
app.get('*', static('built/project/code'));
I wasnt able to find anything talking about redirects not working in the .use method. But apparently it is not allowed.
Here is my solution.
const redirect = () => (res, resp, next) => {
if (/* redirect condition met */) {
return resp.status(302).redirect(`https://example.com/${path_logic()}`);
} else {
return next();
}
}
app.get('*', [
redirect(),
static('built/project/code')
]);
The only logic difference here is the redirection function only seem to work when combined with a request handler (.get .post etc), but not .use.
I see a lot of use next in node.js.
What is it, where does it come from? What does it do? Can I use it client side?
Sorry it's used for example here:
http://dailyjs.com/2010/12/06/node-tutorial-5/
look for the loadUser function.
This appears to be a variable naming convention in Node.js control-flow code, where a reference to the next function to execute is given to a callback for it to kick-off when it's done.
See, for example, the code samples here:
http://blog.mixu.net/2011/02/02/essential-node-js-patterns-and-snippets/
Let's look at the example you posted:
function loadUser(req, res, next) {
if (req.session.user_id) {
User.findById(req.session.user_id, function(user) {
if (user) {
req.currentUser = user;
return next();
} else {
res.redirect('/sessions/new');
}
});
} else {
res.redirect('/sessions/new');
}
}
app.get('/documents.:format?', loadUser, function(req, res) {
// ...
});
The loadUser function expects a function in its third argument, which is bound to the name next. This is a normal function parameter. It holds a reference to the next action to perform and is called once loadUser is done (unless a user could not be found).
There's nothing special about the name next in this example; we could have named it anything.
It is naming convention used when passing callbacks in situations that require serial execution of actions, e.g. scan directory -> read file data -> do something with data. This is in preference to deeply nesting the callbacks. The first three sections of the following article on Tim Caswell's HowToNode blog give a good overview of this:
http://howtonode.org/control-flow
Also see the Sequential Actions section of the second part of that posting:
http://howtonode.org/control-flow-part-ii
It's basically like a callback that express.js use after a certain part of the code is executed and done, you can use it to make sure that part of code is done and what you wanna do next thing, but always be mindful you only can do one res.send in your each REST block...
So you can do something like this as a simple next() example:
app.get("/", (req, res, next) => {
console.log("req:", req, "res:", res);
res.send(["data": "whatever"]);
next();
},(req, res) =>
console.log("it's all done!");
);
It's also very useful when you'd like to have a middleware in your app...
To load the middleware function, call app.use(), specifying the
middleware function. For example, the following code loads the
myLogger middleware function before the route to the root path (/).
var express = require('express');
var app = express();
var myLogger = function (req, res, next) {
console.log('LOGGED');
next();
}
app.use(myLogger);
app.get('/', function (req, res) {
res.send('Hello World!');
})
app.listen(3000);