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

Posted

技术标签:

【中文标题】将 Express.js 3 与数据库模块一起使用,在哪里初始化数据库客户端?【英文标题】:Using Express.js 3 with database modules, where to init database client? 【发布时间】:2013-03-20 00:14:58 【问题描述】:

知道 Express.js 几乎将其留给开发人员来决定应用程序结构,并且在阅读了很多关于 SO 的建议(例如,参见 link1 和 link2)以及检查 example in official repo 之后,我我仍然不确定我正在做的事情是否是最好的前进方式。

假设我在我的应用程序中广泛使用 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,我的问题是

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

更新:

我为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】:

如果我分享一下我最近如何使用Patio(一个 SQL ORM)实现一个项目,也许会很有用。更多背景知识:我使用的 MVC 框架是 Locomotive,但这绝对不是必需的(Locomotive 没有 ORM,它将实现您如何处理模型和数据库的方式留给开发人员,类似于 Express)。

Locomotive 有一个名为“initializers”的构造,它只是在应用启动期间加载的 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;
  
;

由于模型注册表将模型类存储在this(即module.exports)中,因此可以从您需要访问模型的其他文件中导入它们:

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

免责声明:这对我有用,YMMV。此外,上面的代码示例没有考虑任何异步要求或错误处理,因此在我的案例中实际实现要复杂一些。

【讨论】:

很有趣,所以你基本上在module.exports 中保留了一个模型集合,我想知道它与在 GLOBAL 中保留模块相比如何 - ***.com/questions/5447771/node-js-global-variables 我认为这是一个品味问题。我自己更喜欢必须执行一些显式操作来检索变量而不是“就在那里”:)

以上是关于将 Express.js 3 与数据库模块一起使用,在哪里初始化数据库客户端?的主要内容,如果未能解决你的问题,请参考以下文章

synchronize.js与express js一起使用

如何将 webpack 与 express 一起使用?

Node.js 设置与everyauth 一起使用的环境特定配置

如何将 Angular JS 与 Leaflet.js 一起使用

express.js 连接模块的问题

Node.js - Express.js JWT 总是在浏览器响应中返回一个无效的令牌错误