How to properly reuse connection to Mongodb across NodeJs application and modules

express, javascript, mongodb, node.js

Solution

You can create a `mongoUtil.js` module that has functions to both connect to mongo and return a mongo db instance:

const MongoClient = require( 'mongodb' ).MongoClient;
const url = "mongodb://localhost:27017";

var _db;

module.exports = {

  connectToServer: function( callback ) {
    MongoClient.connect( url,  { useNewUrlParser: true }, function( err, client ) {
      _db  = client.db('test_db');
      return callback( err );
    } );
  },

  getDb: function() {
    return _db;
  }
};

To use it, you would do this in your `app.js`:

var mongoUtil = require( 'mongoUtil' );

mongoUtil.connectToServer( function( err, client ) {
  if (err) console.log(err);
  // start the rest of your app here
} );

And then, when you need access to mongo somewhere else, like in another `.js` file, you can do this:

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

db.collection( 'users' ).find();

The reason this works is that in node, when modules are `require`'d, they only get loaded/sourced once so you will only ever end up with one instance of `_db` and `mongoUtil.getDb()` will always return that same instance.

Note, code not tested.

Problem

I've been reading and reading and still am confused on what is the best way to share the same database (MongoDb) connection across whole NodeJs app. As I understand connection should be open when app starts and reused between modules. My current idea of the best way is that `server.js` (main file where everything starts) connects to database and creates object variable that is passed to modules. Once connected this variable will be used by modules code as necessary and this connection stays open. E.g.: ``` var MongoClient = require('mongodb').MongoClient; var mongo = {}; // this is passed to modules and code MongoClient.connect("mongodb://localhost:27017/marankings", function(err, db) { if (!err) { console.log("We are connected"); // these tables will be passed to modules as part of mongo object mongo.dbUsers = db.collection("users"); mongo.dbDisciplines = db.collection("disciplines"); console.log("aaa " + users.getAll()); // displays object and this can be used from inside modules } else console.log(err); }); var users = new(require("./models/user"))(app, mongo); console.log("bbb " + users.getAll()); // not connected at the very first time so displays undefined ``` then another module `models/user` looks like that: ``` Users = function(app, mongo) { Users.prototype.addUser = function() { console.log("add user"); } Users.prototype.getAll = function() { return "all users " + mongo.dbUsers; } } module.exports = Users; ``` Now I have horrible feeling that this is wrong so are there any obvious problems with this approach and if so how to make it better?

Original source

Related problems