繁体   English   中英

如何在没有循环依赖关系的模型之间正确共享Hapi Joi验证模式

[英]How to properly share Hapi Joi validation schemas between models without circular dependency

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

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

在每个模块中moduleXRoute创建关联从处理器的路线moduleXController并从验证moduleXValidate

由于我使用淳佳,我对输入数据执行一些测试,但如问题来了,我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;

因此,解决该问题的好方法是什么?

我发现最简单的方法是将所有模式集中在所有验证程序可能需要的单个文件中,但是我觉得这与组件体系结构矛盾。

最好的方法是拥有一个中心点,在该点上,模式的通用部分将保留在中心位置,并在需要时加载到所需的模式中。

我最终决定通过使用依赖项注入来解决“鸡与蛋”问题。 在上面的示例中,我会做类似的事情

//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;

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM