Express js routing with query string - node.js

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
}

Related

prevent express middleware from executing for same parent path

This is my code when.
I am hitting put API it is executing middleware 3 times but it should execute for put API only.
app.use('/api/user', MiddlewareFun);
app.get('/api/user', (req, res) => {
//do something
});
app.use('/api/user', MiddlewareFun);
app.post('/api/user', (req, res) => {
//do something
});
app.use('/api/user', MiddlewareFun);
app.put('/api/user', (req, res) => {
//do something
});
please don't say use like this.
app.put('/api/user', MiddlewareFun, (req, res) => {
//do something
});
Well, it's happening, because you've made it to. If you want the middleware, to be executed at only selected method, you have to specify it. For example:
Instead of doing:
app.use('/api/user', MiddlewareFun)
app.put('/api/user', (req, res) => {
//do something
})
replace use method with put. As you'd bind regular route:
app.put('/api/user', MiddlewareFun)
app.put('/api/user', (req, res) => {
//do something
})
Also, one more thing. You don't have to duplicate your middleware call before every route declaration. If you want to apply a middleware to your whole router, you can use .use() (as you did), or .all(); which will result in the same behavior.
The middlewares in Express are binded to app or to router.
The solution to yuur problem is to check the method of the request object at the middleware
let MiddlewareFun = function (req, res, next) {
if (req.method === 'PUT') {
// do something
}
next()
}
app.use('/api/user', MiddlewareFun);
The answer is, You need to write express middleware which is part of your app or router. You can write as many middlewares you want, but in your case you just need it only once and here is the implementation of that.
const MiddlewareFun = function(req, res, next) {
// req is object which consist of information about request made.
// From req object you can get method name which is called.
if(req.method.toLowerString() === 'put') {
// your logic goes here
}
next();
}
app.use('/api/user', MiddlewareFun);
app.get('/api/user', (req, res) => {
//do something
});
app.post('/api/user', (req, res) => {
//do something
});
app.put('/api/user', (req, res) => {
//do something
});

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

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.

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();
}
})

Passing extra parameters to route handlers in Express

I'm relatively new to Express, and I'm looking for a way to make routes more reusable. In my app, I will have quite a few routes that can be passed to a generic handler, but will have different templates.
Example:
app.get('/about', function(req, res) {
res.render('about.html');
});
app.get('/', function(req, res) {
res.render('home.html');
});
While this example is contrite, I have 30+ such routes. What I would like to be able to do is something like this:
app.get('/about', generic.render('about.html'));
or otherwise somehow pass the template name to the function that returns res.render Is this possible in Express? All of my attempts to work around this result in variables being undefined.
I would prefer to not do something like this, tightly coupling my route parameters and template names:
app.get('/:template', function(req, res) {
res.render(req.params.template + '.html');
});
You could just make a a simple middleware that does this for you. Example:
function simpleRender(file, opts) {
opts || (opts = {});
return function(req, res) {
res.render(file, opts);
};
}
Then just use it like:
app.get('/about', simpleRender('about.html'));
app.get('/', simpleRender('home.html'));
This is how I do it:
const handler = (req, res, template) => {
res.render(template)
}
app.get('/about', (req, res) => {
handler(req, res, 'about.html')
})
This is a best practice for me
app.get('/:template',(req, res, next) => {
res.locals = `${template}.html`;
next();
},
renderMethod
);
function renderMethod(req, res){
res.render(res.locals)
}

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