8

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.

1 Answer 1

14

Single Parameter

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

Multiple Parameters

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.

Unknown Parameters

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.

Sign up to request clarification or add additional context in comments.

2 Comments

interesting idea! how would you handle additional optional parameters? e.g. /api/events?org_id=1&event_name=name&etc..
See the edit to my answer. You should know the (acceptable) number and type of parameters that will be coming in.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.