I am building a REST API on top of Express 4. For a path lets say GET /api/users
I want to query my users collection accordingly to optional queryParams.
So a call to the API could look like this host:port/api/users?city=Berlin
In this case name
is omitted and doesn't influence the query, whereas city
has to match.
I managed to do this with the following hack. Is there a better way than that?
Users.statics.customFilter = function(qP){
return this.find({
$and: [
{$or: [{undefined: {$eq: qP.city}}, {'city': qP.city}]},
{$or: [{undefined: {$eq: qP.name}}, {'name': qP.name}]}
]
});
mongoose.model('User', Users);
I'm calling this static function from the mongoose schema like this…
const User = mongoose.model('User');
app.get('/api/users', (req, res) => {
User.customFilter(req.query)
.exec((err, results) => {
if (err) return next(err);
res.json(results);
});
});
Best Answer
It seems to me that in essence,
User.find(req.query)
should do what you want:Of course, you have to decide what should happen if no parameters are passed (in the example above, it would become a query that would match all users, which may not be what you want).
Also, you should probably filter
req.query
so it only contains fields that are defined in your schema.