Let several modules use the same mongo instance

I'm building a larger web app, where the routes are divided into separate files. All routes need a connection to the db, and therefore all of them require mongoskin, which is the module I'm using for MongoDb. Like this:

var mongo = require('mongoskin');

But soon after I realised that only require the mongoskin wasn't enough for the routes to be able to talk to the db. Because in my main app.js file I also made additional "configurations".

db = mongo.db('mongodb://localhost/dbName', {native_parser:true});
db.open(function(err) {
if (!err) {
    console.log('Connected to mongodb://localhost/dbName');
}
});
db.bind('clients');
db.bind('invoices');

I needed this db object to be shared aswell...

My first attempt was to wrap the route file in a exported function that takes an argument. This argument is passed in when I require the routes.js in my main app.js. This worked out fine, but I wasn't really fond of this solution... I think it became a bit messy.

My second approach, which I'm using right now, is to make a separate module of the whole db object.

var mongo = require('mongoskin');

var db = null;

module.exports =  {
    initAndGetDb: function () {
        db = mongo.db('mongodb://localhost/dbName', {native_parser:true});
        db.open(function(err) {
            if (!err) {
                console.log('Connected to mongodb://localhost/dbName');
            }
        });
        db.bind('clients');
        db.bind('invoices');

        return(db);
    },
    getDb: function () {
        return(db);
    }
};

In my main app.js

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

And in my routes.js

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

Question: Is this approach a good working solution for sharing a db connection (and maybe other things in a similar fashion)? If you can see any problem with this, please let me know...

Overall I think this is fine, but you could simplify it to just:

//your db.js module
var mongo = require('mongoskin');
var db = mongo.db('mongodb://localhost/dbName', {native_parser:true});
db.bind('clients');
db.bind('invoices');
db.open(function(err) {
  if (err) {
    console.error('Could not connect to db', err);
    return;
  }
  console.log('Connected to mongodb://localhost/dbName');
});
module.exports = db;

The first time your code does require("./db");, the top-level code in db.js will run and connect to the db. When other modules require it, they will get access to the db without re-running the top level code and reconnecting.

Note that to be truly ready for production you would need to enhance this with:

  • get DB connection details from some configuration system (env vars or a helper module)
  • More robust logging
  • Graceful handling of disconnects and reconnects while the app is running
  • Graceful handling of the db being down when the web app starts
  • retry/backoff logic around connecting/reconnecting
  • Decide what the webapp does when it can't reach the DB. Show a fail whale page or exit the process.