Let's say I have two events:
{"id":1, "name":"event1"},
{"id":2, "name":"event2"}
And I am writing a REST API to retrieve events. This API takes an optional parameter, id
, which if present, returns events specific to that id only, and returns all events if null.
So api/events?id=1
should return event1
only, while api/events
will return both event1
and event2
. Currently I am using an if-else statement, but this is clearly not scalable if I have more optional parameters. Is there any way to express this as a MongoDB query instead?
Code:
app.get('/api/events', function (req, res) {
var _get = url.parse(req.url, true).query,
eventCollection = db.collection('events');
// Parameters passed in URL
var page = (_get.page) ? _get.page * 10 : 0,
org_id = (_get.org_id) ? parseInt(_get.org_id) : "";
if (org_id == "") {
eventCollection.find({
}, {
limit: 10,
skip: page
}).toArray(function(err, events) {
if (!err) {
res.json(
events
);
}
});
} else {
eventCollection.find({
org_id: org_id
}, {
limit: 10,
skip: page
}).toArray(function(err, events) {
if (!err) {
res.json(
events
);
}
});
}
});
P.S. I am using the Node.js Javascript driver for MongoDB.
As query parameters are not a fixed part of a path, they can be optional and can have default values.
By Params Keyword: You can implement optional parameters by using the params keyword. It allows you to pass any variable number of parameters to a method. But you can use the params keyword for only one parameter and that parameter is the last parameter of the method.
Optional Parameters are parameters that can be specified, but are not required. This allows for functions that are more customizable, without requiring parameters that many users will not need.
A method that contains optional parameters does not force to pass arguments at calling time. It means we call method without passing the arguments. The optional parameter contains a default value in function definition. If we do not pass optional argument value at calling time, the default value is used.
One idea would be to set the query object with the ternary operator.
Something like the following:
app.get('/api/events', function (req, res) {
var _get = url.parse(req.url, true).query,
eventCollection = db.collection('events');
// Parameters passed in URL
var page = (_get.page) ? _get.page * 10 : 0,
query = (_get.org_id) ? {org_id:parseInt(_get.org_id)} : {};
eventCollection.find(query, {limit: 10, skip: page}).toArray(function(err, events){
if (!err) {
res.json(
events
);
}
});
});
Having that been said, if you have multiple parameters to query, one way would be to build a JSON object like below:
app.get('/api/events', function (req, res) {
var _get = url.parse(req.url, true).query,
eventCollection = db.collection('events');
// Parameters passed in URL
var page = (_get.page) ? _get.page * 10 : 0,
query = {};
(_get.org_id) ? (query.org_id = parseInt(_get.org_id)) : "";
(_get.name) ? (query.name = _get.name) : "";
(_get.param3) ? (query.name = _get.param3) : "";
eventCollection.find(query, {limit: 10, skip: page}).toArray(function(err, events){
if (!err) {
res.json(
events
);
}
});
});
I'll leave it to you to take the block where the query parameters are defined and turn it into a for loop.
If you don't know the number of parameters ahead of time, one option is to build a string and then convert it to a JSON object. However, I don't recommend this. It's dangerous to let users define parameters.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With