使用Express.js 3与数据库模块,在哪里初始化数据库客户端?

时间:2013-03-29 09:44:05

标签: node.js model-view-controller express redis

知道Express.js在决定应用程序结构方面几乎留给了开发人员,并且在阅读了很多有关SO的建议之后(例如,请参阅link1link2)以及检查{ {3}},我仍然不确定我所做的是最好的前进方式。

假设我在我的应用程序中广泛使用Redis,并且我有多个需要redis客户端运行查询的“模型”,最好在主app.js中初始化redis客户端,如下所示:

var db = redis.createClient();
var models = require('./models')(db);
var routes = require('./controllers')(models);

或者在每个模型中初始化redis会更好,然后让每个控制器都需要感兴趣的模型吗?

后一种方法是我正在使用的,看起来不那么干。但是以最佳方式传递模型实例?请注意,我在这里加载多个模型/控制器 - 我不知道如何修改我的设置以将redis客户端正确地传递给每个模型。

//currently in models/index.js

exports.home = require('./home.js');
exports.users = require('./user.js');

TL; DR,我的问题是

  1. 哪里最好在MVC模式应用程序中初始化redis客户端?
  2. 如何将此redis客户端实例传递给具有require('./models')(db)
  3. 的多个模型

    更新

    我尝试了index.js的不同方法,使用module.exports来返回模型/控制器的对象:

    module.exports = function(models){
    
      var routes = {};
    
      routes.online = require('./home.js')(models);
      routes.users = require('./user.js')(models);
    
      return routes;
    
    };
    

    现在看起来好像是个好主意?

1 个答案:

答案 0 :(得分:3)

如果我分享我最近使用SQL ORM Patio实现项目的方式,这可能很有用。更多背景:我使用的MVC框架是Locomotive,但这绝对不是一个要求(机车没有ORM,它实现了如何处理开发人员的模型和数据库,类似于Express )。

Locomotive有一个名为'initializers'的构造,它只是在app启动时加载的JS文件;他们所做的事取决于开发人员。在我的项目中,一个初始化程序配置了数据库。

初始化程序建立了实际的数据库连接,还负责加载model目录中的所有JS文件。在伪代码中:

registry = require('model_registry'); // see below
db       = createDatabaseConnection();
files    = fs.readDirSync(MODEL_DIRECTORY);
for each file in files:
  if filename doesn't end with '.js':
    continue
  mod = require(path.join(MODEL_DIRECTORY, filename));
  var model = mod(db);
  registry.registerModel(model);

模型看起来像这样:

// models/mymodel.js
module.exports = function(db ) {
  var model = function(...) { /* model class */ };
  model.modelName = 'MyModel'; // used by registry, see below
  return model;
};

模型注册表是一个非常简单的模块,用于存放所有模型:

module.exports = {
  registerModel : function(model) {
    if (! model.hasOwnProperty('modelName'))
      throw Error('[model registry] models require a modelName property');
    this[model.modelName] = model;
  }
};

因为模型注册表将模型类存储在thismodule.exports)中,所以可以从需要访问模型的其他文件中导入它们:

// mycontroller.js
var MyModel = require('model_registry').MyModel;
var instance = new MyModel(...);

免责声明:这对我有用,YMMV。此外,上面的代码示例没有考虑任何异步要求或错误处理,所以在我的情况下实际的实现更精细。