Nick Parsons
Nick Parsons

Reputation: 8607

Abstracting Mongoose with Restify

I'm curious if anyone could provide some insight on the best way to abstract an API built with Node.js + Restify + Mongoose. After coming from an MVC / PHP background, it's interesting to find that there's not string/defined structure for Node applications.

As of now, I have my app.js file that auto loads my routes.js file, all model js files, etc.

The confusion is primarily in how my routes are supposed to interact with data from Mongo. Here is a basic rundown on how my code is layed out.

app.js:

/**
 * Require Dependencies
 */
var restify    = require('restify')
    , mongoose = require('mongoose')
    , config   = require('./config')
    , routes   = require('./routes');

/**
 * Create Server & Define Settings
 */
var server = restify.createServer({
    name: config.name,
    version: config.version
});

/**
 * Common Handlers
 */
server.use(restify.acceptParser(server.acceptable));
server.use(restify.queryParser());
server.use(restify.bodyParser());
server.use(restify.jsonp());

/**
 * Connect to Mongo Database
 */
 mongoose.connect(config.mongo.uri, function(err) {

    // assign connection to var so we can pass it down the chain
    var db = mongoose.connection;

    // handle connection error
    db.on('error', console.error.bind(console, 'connection error:'));

    // handle connection success
    db.once('open', function callback () {

        /**
         * Start Routing API Calls
         */
        routes.route(server, db);

    });

});

/**
 * Start Server & Bind to Port
 */
server.listen(config.port, function () {
    console.log('%s v%s listening on port %s in %s mode.', server.name, server.version,          config.port, config.env);
});

routes.js:

module.exports.route = function(server, db) {

    var Users = require('./models/users.js');

    /**
     * Users
     */

    server.get('/users', function (req, res, next) {

        res.send(Users.list(db, req, res));

        return next();

    });

    server.get('/users/:user_id', function (req, res, next) {

        res.send(Users.get(db, req, res));

        return next();

    });

}  

models/users.js:

// fake database
var users = [
    {
        name: 'Nick P',
        email: '[email protected]'
    },
    {
        name: 'Zack S',
        email: '[email protected]'
    }
];

exports.list = function(db, req, res) {

return users;

};

exports.get = function(db, req, res) {

    return users[req.params.user_id];

};

As you can see, I'm using a "fake database" that is a simple object. Where / how could I introduce a Mongoose layer to communicate with our database? I'm mostly concerned with how I should use schemas and exports. Any code examples, or direction would be awesome.

Upvotes: 4

Views: 3332

Answers (1)

Jean-Philippe Bond
Jean-Philippe Bond

Reputation: 10679

Here a simple example of what I usually do with Express, it's kind of the same thing with Restify. You can manage your Mongoose schemas in the same way but in your Restify routes.

app.js :

var express = require('express');     
var app = express();

app.configure(function () {
    app.use(express.logger('dev'));
    app.use(express.bodyParser());
});

// connection to mongoDB
var mongoose = require('mongoose');
mongoose.connect('mongodb:mongoURI');    

var user = require('./routes/users');

app.get('/users/list', user.list);

app.listen(3000);

models/user.js :

var mongoose = require('mongoose')
   ,Schema = mongoose.Schema
   ,ObjectId = Schema.ObjectId;

var userSchema = new Schema({
    id: ObjectId,
    name: {type: String, default: ''},
    email: {type: String, default: ''}
});

module.exports = mongoose.model('User', userSchema);

routes/users.js :

var User = require('../models/user.js');

exports.list = function(req, res) {
    User.find(function(err, users) {
        res.send(users);
    });
};

Upvotes: 7

Related Questions