Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ExpressJS and passing variables between separate route files

I'm using ExpressJs with Node.js and have put all my routes into a 'routes' folder.

On the server, I do my DB connection, then define my routes, like this:

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

var db;
dbconnect = new mongo.Db(config.mongo_database, new mongo.Server(config.mongo_host, config.mongo_port, {}), {});
dbconnect.open(function (err, db) {

  db.authenticate(config.mongo_user, config.mongo_pass, function (err, success) {
    if (success) {

      //routes/index.js
      app.get('/', routes.index);

      //routes/users.js
      app.get('/users', routes.users);

    }
  });
});

I want to access the 'db' object inside each of these routes javascript files. How would I pass that from this 'app.js' file to the index.js or users.js?

Thank you!

like image 374
dzm Avatar asked Apr 02 '12 16:04

dzm


2 Answers

If you write your database abstraction in it's own file/module, you can then reuse it throughout your codebase as needed by just require()'ing it where needed. It won't get re-created if you write it correctly, and can just get initialized once on application startup like your example does.

//contents of your database.js file
var database;

module.exports = {

    init : function(config, cb) {
        database = new mongo.Db(config.mongo_database, new mongo.Server(config.mongo_host, config.mongo_port, {}), {});
        database.open(function (err, db) {  
            db.authenticate(config.mongo_user, config.mongo_pass, cb);
        });
    },

    query : function(params, cb) {
        database.query(params, cb);
    }   

};

This is a trivial example, but hopefully it gets the point across. In controllers or any files where you need that database object, you just...

var db = require('database');

db.init(params, function(err, db) {
    ...
});


db.query(params, function(err, db) {
    ...
});

The benefits are you now have a loosely coupled database object that can be used anywhere in your application just like any other node module through the require statement.

like image 119
Brad Harris Avatar answered Sep 18 '22 16:09

Brad Harris


One suggestion is to expose your routes via a function which accepts a db parameter:

routes.js:

module.exports = function(db) {
    return {
        index: function(req, res, next) {
            // Funky db get stuff
        }
    }
}

Wrapping values in a closure like this and returning an object with more functions is a useful pattern, sometimes called "Revealing Module Pattern". It shows the dependencies clearly, allowing for easy testing (using e.g. a mock db object) while still using a flexible functional approach.

like image 36
Linus Thiel Avatar answered Sep 19 '22 16:09

Linus Thiel