Skip to content Skip to sidebar Skip to footer

Sharing Objects And Avoiding Globals In Node.js

What would be the most appropriate way of sharing the database connection in the below snippet ( the db variable) with my routers/controllers without turning the db variable into a

Solution 1:

Try look at this way:

app.js:

var mongo = require('mongoskin'),
db = mongo.db(config.db.adress);

app.use(function(req, res, next) {
    db.open(function(err, data) {
        (err) ? res.send('Internal server error', 500) : next();
    });
});

require('./controllers/users')(app, db);

controllers/users.js:

module.exports = function (app, db) {

    app.post('/users', function(req, res, next) {
        // Your create function// Link to db exists here
    });

};

Solution 2:

I don't have any experience with mongoskin but Mongoose neatly sidesteps this problem by returning a Singleton instance of Mongoose every time you require it.

Which allows you to create a connection once (on app init, usually) and simply use it by querying Models when you need it.

It also allows you to define your models once like this:

var mongoose = require('mongoose'),

  TodoSchema = new mongoose.Schema({
    title: { 'type': String, 'default': 'empty todo...' },
    order: { 'type': Number },
    done: { 'type': Boolean, 'default': false }
  });

mongoose.model('Todo', TodoSchema);

And then use them wherever you need to like this:

var mongoose = require('mongoose'),
      Todo = mongoose.model('Todo');

More information on how Mongoose works like this, with example code can be found in this answer here.

From mongoskin's docs, it looks like you have to connect each time you want to use it, which you could simplify by wrapping the db connection in a file you can require:

db.js

exports.db = require('mongoskin').db('myProject-' + process.env.NODE_ENV);

use it:

var db = require('./db');

db.open(function(err, data) {
        (err) ? res.send('Internal server error', 500) : next();
    });

The method above, where db is passed as an argument to every function that may need it, leads to callback soup and should be avoided if possible.

Solution 3:

I ended up using Vadim Baryshev's answer and took it a bit further by creating a State module holding commonly used modules together, to keep things tidy:

state.js:

module.exports = {
    mongo: require('mongoskin'),
    db: require('mongoskin').db('myProject-' +process.env.NODE_ENV )
} 

app.js:

var state = require('./state');
require('./controllers/Users')(app, state);

controllers/users.js:

module.exports = function(app, state) {

    app.post('/users', function(req, res, next) {
        state.db.find({}, function(doc, err) {});
    });

};

Solution 4:

As suggested by @Jed Watson, the moongoose module uses a singleton (anti?) pattern, which is enforced by the require/export mechanism. Here is the specific bit of code :

(as found here : https://github.com/LearnBoost/mongoose/blob/master/lib/index.js)

/*!
 * The exports object is an instance of Mongoose.
 *
 * @api public
 */varmongoose=module.exports = exports = newMongoose;

Post a Comment for "Sharing Objects And Avoiding Globals In Node.js"