【问题标题】:How to properly share Hapi Joi validation schemas between models without circular dependency如何在没有循环依赖的模型之间正确共享 Hapi Joi 验证模式
【发布时间】:2015-11-09 14:05:26
【问题描述】:

我正在使用 HAPI 和 Joi 创建一个 API 来验证输入,但在不同模块之间共享我的验证架构时遇到了麻烦。 我正在使用一个看起来像这样的面向组件的架构

components
|_ moduleA
   |_ moduleAController
   |_ moduleAModel
   |_ moduleARoute
   |_ moduleAValidate
|_ moduleB
   |_ moduleBController
   |_ moduleBModel
   |_ moduleBRoute
   |_ moduleBValidate
|_ moduleC
...

在每个模块中,moduleXRoute 创建一个路由,将来自moduleXController 的处理程序和来自moduleXValidate 的验证器关联起来。

当我使用 Joi 时,我正在对输入数据进行一些测试,问题出在哪里,我的 moduleA 保留了 moduleB 的列表,而我的 moduleB 保留了对 moduleA 的引用,因此这个在验证器中暗示:

var moduleASchema = {
    _id: Joi.objectId(),
    name: Joi.string().required(),
    moduleB: Joi.array().items(Joi.alternatives().try(Joi.objectId(), moduleBSchema)),
};

var moduleBSchema = {
        _id: Joi.objectId(),
        name: Joi.string().required(),
        moduleA: Joi.alternatives().try(Joi.objectId(), moduleASchema),
};

这就是为什么,我认为 moduleAValidatemoduleBValidate 公开其他模块可以使用的 moduleASchemamoduleBSchema 是个好主意。

问题在于它产生了循环依赖问题,因为在上述情况下,我会:

//moduleAValidate.js
var moduleBSchema = require('../moduleBValidate').moduleBschema;

//moduleBValidate.js
var moduleASchema = require('../moduleAValidate').moduleAschema;

那么,解决问题的好方法是什么?

我发现一种简单的方法是将所有模式集中在一个文件中,这可能是所有验证器都需要的,但我觉得这与组件架构相矛盾。

【问题讨论】:

    标签: javascript architecture hapijs joi


    【解决方案1】:

    最好的方法是有一个中心点,将架构的公共部分保存在一个中心位置,并在需要时加载到所需的架构中。

    【讨论】:

      【解决方案2】:

      我最终决定使用依赖注入来解决先有鸡还是先有蛋的问题。 在上面的例子中,我会做类似的事情

      //moduleBValidate.js
      var moduleBSchema = new (require('moduleBSchema.js'))();
      var moduleASchema = new (require('moduleASchema.js'))(moduleBSchema); // Here I use dependency injection for injecting moduleBSchema in moduleASchema
      
      //moduleAValidate.js
      var moduleASchema = new (require('moduleASchema.js'))();
      var moduleBSchema = new (require('moduleBSchema.js'))(moduleASchema);
      

      我以这种方式构建了 joi 模式:

      function moduleASchema(moduleBSchema, moduleCSchema...) { // Here we put all dependencies of moduleASChema
          moduleBSchema = moduleBSchema || Joi.object();
          moduleCSchema = moduleCSchema || Joi.object();
          ...
      
          this.schema = {
              name: Joi.string().required(),
              moduleBRef: Joi.alternatives().try(Joi.objectId(), moduleBSchema),
              moduleCRef: Joi.alternatives().try(Joi.objectId(), moduleCSchema)
          };
          return this.schema;
      }
      
      module.exports = SiteSchema;
      

      【讨论】:

        猜你喜欢
        • 2020-09-19
        • 2019-10-10
        • 1970-01-01
        • 1970-01-01
        • 2019-02-15
        • 2015-10-28
        • 2018-09-24
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多