Joi验证:如何批量为多个schema对象开启允许未知键配置
Joi 批量为所有Schema统一配置允许未知键的实现方案
针对你手头近百个对象Schema需要统一开启允许未知键校验的场景,完全可以通过全局配置或工具封装实现,不需要逐个重复编写相同规则,符合DRY原则:
方案1:基于Joi自带的defaults()方法做全局统一配置(最推荐)
Joi原生支持通过defaults()方法定义全局默认规则,所有后续基于该实例生成的Schema都会自动继承你配置的默认规则,不需要在每个Schema后单独补写配置:
- 新建独立的Joi配置文件(比如
src/utils/joi.js),内容如下:const JoiBase = require('joi'); const Joi = JoiBase.defaults((schema) => { // 仅对对象类型的Schema生效,避免影响字符串、数字等基础类型的校验逻辑 if (schema.type === 'object') { return schema.options({ allowUnknown: true }); } // 非对象类型的Schema保持原有规则不变 return schema; }); module.exports = Joi; - 把项目里所有原来引入原生Joi的代码,全部替换成上面导出的自定义Joi实例即可。
你原来写的对象Schema完全不用做任何改动,自动就带上了允许未知键的规则,且这套配置会自动对所有层级的嵌套对象Schema生效,不需要单独给子对象重复加规则。
如果后续有个别Schema需要特殊配置(比如某个接口严格禁止未知键),直接在对应Schema后面单独加.options({ allowUnknown: false })即可,后定义的规则优先级高于全局默认配置,不会出现冲突。
方案2:封装统一的对象Schema生成工具
如果不想修改全局Joi的默认行为(比如需要和其他项目共用Joi逻辑),可以封装一个统一的工厂函数替代原生的Joi.object()调用:
// 工具函数定义 const createObjectSchema = (schemaKeys) => { return Joi.object(schemaKeys).options({ allowUnknown: true }); }; // 替换原有Schema写法 // 原写法:const userSchema = Joi.object().keys({a: Joi.string()}).unknown(true) // 新写法: const userSchema = createObjectSchema({ a: Joi.string().required(), b: Joi.string().required() });
这种方式改动量很小,只需要把每个Schema的定义逻辑换成调用统一工具函数即可,不会影响其他基础类型的校验逻辑。
方案3:批量处理已写好的存量Schema
如果已经写完了上百个零散的Schema,不想逐个修改文件,可以先把所有Schema统一导入汇总,再通过遍历批量补上配置:
// 汇总所有分散在各文件的Schema const allSchemas = { userSchema: require('./schemas/user'), orderSchema: require('./schemas/order'), // ... 其他所有Schema }; // 遍历批量给对象类型的Schema补充规则 const processedSchemas = Object.fromEntries( Object.entries(allSchemas).map(([schemaName, schema]) => { // 仅处理对象类型的Schema,避免影响非对象类型的校验逻辑 if (schema.type === 'object') { return [schemaName, schema.options({ allowUnknown: true })]; } return [schemaName, schema]; }) );
后续业务代码直接使用processedSchemas里的校验对象即可,不需要改动原有Schema文件的代码。
注意:你提到的
.unknown(true)和.options({ allowUnknown: true })是完全等价的写法,没有功能差异,全局配置时用哪种都可以。
内容的提问来源于stack exchange,提问作者Mohnish M
相关产品推荐
相关产品推荐

