0

0

如何复用 Joi Schema 的属性定义而不继承验证规则

霞舞

霞舞

发布时间:2026-01-05 19:28:02

|

420人浏览过

|

来源于php中文网

原创

如何复用 Joi Schema 的属性定义而不继承验证规则

本文介绍在 joi 中如何安全复用基础 schema 的字段定义,避免意外继承 `.xor()`、`.messages()` 等链式配置,通过 `object.keys()` 方法实现纯净的属性扩展。

Joi 的 Schema 实例是不可变(immutable)的,每次调用 .xor()、.messages()、.requiredKeys() 等方法都会返回一个全新 Schema 实例,而非修改原对象。这意味着:直接对已配置 .xor() 和 .messages() 的 Schema 调用 .keys() 或 .append(),不会污染原始定义,但若你从一个“已增强”的 Schema 出发(如 baseSchema.xor(...).messages(...)),再调用 .keys(),新 Schema 仍会携带之前所有规则 —— 这正是问题根源。

✅ 正确做法是:仅对“纯净”的基础 Schema(即仅含 .object({ ... }) 定义、未附加任何校验逻辑或消息)调用 .keys()

以下为推荐实践:

DubbingX智声云配
DubbingX智声云配

多情绪免费克隆AI音频工具

下载
const Joi = require('@hapi/joi'); // 或 @joi/browser(v17+)

// ✅ 第一步:定义纯净的基础字段结构(无 xor / messages)
const baseFields = Joi.object({
  a: Joi.string().trim().empty(null, ''),
  b: Joi.string().guid().empty(null),
});

// ✅ 第二步:基于 baseFields 构建不同用途的完整 Schema
const firstSchema = baseFields
  .xor('a', 'b')
  .messages({
    'object.missing': 'One of "a", "b" is required.',
    'object.xor': 'Only one of "a", "b" is allowed.',
  });

const extendedSchema = baseFields.keys({
  c: Joi.string().trim(),
});

const secondSchema = extendedSchema
  .xor('a', 'b', 'c')
  .messages({
    'object.missing': 'One of "a", "b", "c" is required.',
    'object.xor': 'Only one of "a", "b", "c" is allowed.',
  });

⚠️ 注意事项:

  • ❌ 避免 const baseSchema = Joi.object({...}).xor(...).messages(...); const reused = baseSchema.keys({...}); —— 此时 reused 仍含 xor 和 messages;
  • ✅ baseFields 必须是 纯 Joi.object() 实例,不带任何链式修饰;
  • .keys() 是浅合并:若传入同名键(如 a),会完全覆盖原定义;如需条件性扩展,可先用 .describe() 提取结构,或借助 Joi.compile() 动态构建;
  • Joi v17+ 中 .keys() 已取代旧版 .add(),语义更清晰,推荐统一使用。

总结:Joi 的复用核心在于分层设计——将字段声明(schema structure)与业务规则(validation logic + messages)解耦。baseFields 扮演「类型契约」角色,而各 .xor() + .messages() 组合则作为面向具体场景的「验证策略」。这种模式不仅提升可维护性,也天然支持单元测试中对字段定义的独立断言。

相关专题

更多
c语言const用法
c语言const用法

const是关键字,可以用于声明常量、函数参数中的const修饰符、const修饰函数返回值、const修饰指针。详细介绍:1、声明常量,const关键字可用于声明常量,常量的值在程序运行期间不可修改,常量可以是基本数据类型,如整数、浮点数、字符等,也可是自定义的数据类型;2、函数参数中的const修饰符,const关键字可用于函数的参数中,表示该参数在函数内部不可修改等等。

520

2023.09.20

append用法
append用法

append是一个常用的命令行工具,用于将一个文件的内容追加到另一个文件的末尾。想了解更多append用法相关内容,可以阅读本专题下面的文章。

342

2023.10.25

python中append的用法
python中append的用法

在Python中,append()是列表对象的一个方法,用于向列表末尾添加一个元素。想了解更多append的更多内容,可以阅读本专题下面的文章。

1066

2023.11.14

python中append的含义
python中append的含义

本专题整合了python中append的相关内容,阅读专题下面的文章了解更多详细内容。

170

2025.09.12

漫蛙2入口地址合集
漫蛙2入口地址合集

本专题整合了漫蛙2入口汇总,阅读专题下面的文章了解更多详细内容。

143

2026.01.06

AO3中文版地址汇总
AO3中文版地址汇总

本专题整合了AO3中文版地址合集,阅读专题下面的文章了解更多详细内容。

81

2026.01.06

python cv2模块教程大全
python cv2模块教程大全

本专题整合了python cv2模块相关教程,阅读专题下面的文章了解更多详细教程。

41

2026.01.06

python创建txt文件教程大全
python创建txt文件教程大全

本专题整合了python创建txt文件相关教程,阅读专题下面的文章了解更多详细内容。

18

2026.01.06

python去掉字符串空格教程大全
python去掉字符串空格教程大全

本专题整合了python去掉字符串空格教程大全,阅读专题下面的文章了解更多详细内容。

2

2026.01.06

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Java 教程
Java 教程

共578课时 | 42.9万人学习

国外Web开发全栈课程全集
国外Web开发全栈课程全集

共12课时 | 0.9万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号