如何在没有循环依赖的模型之间正确共享Hapi-Joi验证模式
How to properly share Hapi Joi validation schemas between models without circular dependency
我正在创建一个使用HAPI和Join验证输入的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),
};
这就是为什么,我认为moduleAValidate
和moduleBValidate
公开其他模块可以使用的moduleASchema
和moduleBSchema
是一个好主意。
问题是它造成了一个循环依赖问题,因为在上面的情况下,我会有:
//moduleAValidate.js
var moduleBSchema = require('../moduleBValidate').moduleBschema;
//moduleBValidate.js
var moduleASchema = require('../moduleAValidate').moduleAschema;
因此,处理这个问题的好方法是什么?
我发现简单的方法是将所有模式集中在一个文件中,这可能是所有验证器所需要的,但我觉得这与组件体系结构相矛盾。
最好的方法是有一个中心点,将模式的公共部分保存在中心位置,并在需要时加载到所需的模式中。
我最终决定使用依赖注入来解决鸡和蛋的问题。在上面的例子中,我会做一些类似的事情
//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;
相关文章:
- 在索引.html和应用.js [node.js] 之间共享变量
- Node.js上的WebSocket,并在所有连接的客户端之间共享消息
- 使用服务(AngularJS)在控制器之间共享数据
- AngularJS中的页面之间共享数据返回空
- 是否可以缓存可下载的文件,并在XHR和非XHR请求之间共享该缓存
- 在Knockoutjs中的ViewModels之间共享变量状态
- 通过共享服务在两个不同ng应用程序中的控制器之间共享数据
- Node.js服务器和浏览器之间共享二进制缓冲区
- 使用Angularjs在两个不同页面的控制器之间共享数据
- 在两个浏览器选项卡之间共享变量范围
- 不同进程之间共享Node.js环境
- 在Angular Bootstrap Modal和父控制器之间共享作用域
- 2ng控制器,并且需要在控制器之间共享数据
- Javascript创建函数,以便在其他函数之间共享变量
- 在控制器angular js之间共享数据
- 在javascript客户端和java服务器之间共享Google Analytics ClientID
- 如何将json文件中的数据提取到对象数组中,并在两个控制器之间共享
- Angular 2,在没有直接关系的两个组件之间共享一个对象
- 在angularJS中使用模态窗口时,在控制器之间共享对象数组
- 在角度上不同控制器之间共享状态