Home » Nodejs » node.js design pattern for creating db connection once

node.js design pattern for creating db connection once

Posted by: admin November 30, 2017 Leave a comment

Questions:

I am looking for help with a design pattern for creating a database connection in my node.js application.

It seems obvious to do:

module1:

var db;
exports.get_db = function(callback) {

  if (db == null) {
    dblibrary.create(connection_params, function(error, conn) {
      if (error == null) {
        db = conn;
        callback(null, db);
      }
    });
  } else {
    callback(null, db);
  }
};

module2:

exports.do_something = function () {
  module1.get_db(function (err, conn) {
    if (err == null) {
      // continue using query
    }
  });
};

It seems painful to have to penalize every single person who wants to get the db connection with the requirement of using a callback.

I could do this:

module1:

var db;

dblibrary.create_connection(connection_params, function (err, conn) {

  if (err != null) {
     console.log("can't create connection");
     console.log(err);
     process.exit();
  } else {
     db = conn;
  }
});

exports.get_db = function() {
  return db;
};

This makes it so that getting the db connection is simple and fast, but means we have to “wait” at node startup time for the connection to be established.

Which is the better design? Is there a better way of doing things?

Answers:

mydb.js module:

var db
exports.db = function() {
    if (db === null) {
        db = dblibrary.createClient()
    }
    return db
}

Other modules:

var db = require('mydb').db()
...
db.query(...)

This creates the DB client instance once at startup. I like this solution because the creation code is encapsulated in a separate module and the other modules can get access to the client with one require() statement.

Questions:
Answers:

Best answer I’ve seen for this is:

in start.js:

    function init_done() {

      app.listen(8080);

    }


init_databases(init_done);

in databases.js:

init_databases(init_done_cb) {

  db.create_async(/* connect data */ , function (err, res) {

    if (err == null) init_done_cb();

  });
}

This way you can do the async startup of the database server without that awkward / dangerous waiting period.

Questions:
Answers:

I wrote connect-once just for solving this kind of problems. There are two main goals, that are achived by this module:

  1. Connection should be initialized before request arrives
  2. Connection should be initialized once, even there are multiple requests coming in at the same time

You can look at express-mongo-db and express-mongoose-db as examples of usage.