1

I am trying to figure out an elegant way to create an REST API for a site that primarily only deals with slugs and not ids. This API is to be written in Node.JS/Express/MongoDB/Mongoose with a Backbone Marionette/Backbone-Relational frontend.

I do not need to ever deal with the typical _id directly, as I aim for my endpoints to be something like /api/articles/some-article-title.

I was originally thinking actually using both _ids and slugs with something like this, getting it to dynamically return an new id field.

// Inside my controller

var slugQuery = function(slug){
    var query = {$or: [{slug: slug}]};
    if (slug.match(/^[0-9a-fA-F]{24}$/)) {
        query.$or.push({_id: slug});
    }
    return query;
}

exports.getProfile = function (req, res) {
    var slug = req.params.slug;

    Profile.findOne( slugQuery(slug), function(err, profile){
        if(err){
            // DB Error
            res.status(400);
            res.end();
        }else if(!profile){
            res.status(404);
            res.end();
        }else{
            res.json( profile.withId() );
        }
    });
};


// Method added to the model

ProfileSchema.methods.withId = function() {
    var json = this.toObject();

    // Use the slug or id
    json.id = json.slug || json._id;

    return json;
};

This seems hacky to me, especially as there are quite a few endpoints/models that would need to function like this. It gets even more complex when I'm wanting to do fairly deep document linking utilising Mongooses populate functionality.

I know theoretically you 'can' literally do away with the ObjectID and store the slug directly inside the _id field, but you cannot update the _id field once its been inserted, and also you would need to update all related links to the document if it did indeed change.

To me, this seems like quite a common need, an REST compliant endpoint with slug based identifiers.

Has anybody had to build something like this before? Any best practices on this?

Thanks!

Stennie
  • 63,885
  • 14
  • 149
  • 175
DigitalJohn
  • 281
  • 3
  • 12
  • http://stackoverflow.com/questions/10018100/identify-item-by-either-an-id-or-a-slug-in-a-restful-api. Note that `populate` works off `_id`, though it doesn't need to be an ObjectId, so if you wanted to utilize it you'd need to replace the `_id` with your slug. Though `populate` doesn't exactly do anything sophisticated; you could always just load related docs in your own subsequent query. Personally I'm a fan of the way SO does URLs. Identified by id, but redirecting to a URL with a human readable suffix (title, username, etc) – numbers1311407 Jan 28 '14 at 15:59
  • I have the same requirement and decided to just use `slug` in my front-end and let `_id` be. I use `_id` internally (to populate) and don't even expose it publicly. Or does your front-end already exist and uses `_id`? – John B. Jan 29 '14 at 17:16

0 Answers0