Reputation: 111
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);
});
});
Upvotes: 2
Views: 15235
Reputation: 1
Because I couldn't find the answer, I will show you how I solved it. I get the parameters from the req.query object. Here I add 2 more queries, that should be always there in my case.
const query = {...req.query, surveyID: id_s, surveyEntityID: id_e};
Then I use mongoose:
let allAnswers = await Answer.find(query);
Upvotes: 0
Reputation: 203304
It seems to me that in essence, User.find(req.query)
should do what you want:
/api/users?city=Berlin → User.find({ city : 'Berlin' })
/api/users?name=John → User.find({ name : 'John' })
/api/users?name=John&city=Berlin → User.find({ city : 'Berlin', name : 'John' })
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.
Upvotes: 9