Express route share variables

Problem

I recently started to learn node.js + Express and found it very interesting.

I have read many postings about sharing variables in routing, and many of them were using module.exports and exports.

I decided to make a function to setup a local variable

routes/test.js

var db;
exports.setup = function(_db){
  db = _db;
};

exports.doit = function(req, res){
  db.get("testToken", function(err, result) { 
    console.log("err: " + err);
    console.log("result: " + result);
    res.send("respond with a resource");
  });
};

app.js

var redis = require("redis");
var db = redis.createClient();
var test = require("./routes/test.js");
test.setup(db);

// configuration...

app.get('/', test.doit);

Is it ok to do things like this?

I want to make sure that I don't make db connections more than once, and sharing vars was the only way I could think of...

Can you make any suggestions?

Thank you!!

Problem courtesy of: chizcracker

Solution

That should work fine. Though, you might consider separating "setup" from the "routes."

Since db is always the same value, you can use Express 3's prototype objects to attach it to the req and/or res objects in all routes:

routes/test.js

exports.doit = function(req, res){
  req.db.get("testToken", function(err, result) { 
    console.log("err: " + err);
    console.log("result: " + result);
    res.send("respond with a resource");
  });
};

app.js

var redis = require("redis");
var db = redis.createClient();
var test = require("./routes/test.js");

// "setup"
express.request.db = express.response.db = db;

// configuration

app.get('/', test.doit);

Though, you can also define "setup" as a custom middleware:

// before: app.use(app.router);
app.use(function (req, res, next) {
  req.db = res.db = db;
  next();
});
Solution courtesy of: Jonathan Lonowski

Discussion

Basically, it looks fine, but it might be module.exports instead of just exports?

Also I would encapsulate the module code into self executed anonymous function to prevent name conflicts and declare module.exports once.

Something like this:

(function() {
  var _db;

  setup = function (db){
    _db = db;
  };

  doit = function (req, res){
    _db.get("testToken", function(err, result) { 
      console.log("err: " + err);
      console.log("result: " + result);
      res.send("respond with a resource");
    });
  };

  module.exports = {
    setup: setup,
    doit: doit
  }
}).call(this);
Discussion courtesy of: skovalyov

This recipe can be found in it's original form on Stack Over Flow.