0

0

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

霞舞

霞舞

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

|

690人浏览过

|

来源于php中文网

原创

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

本文介绍在 joi 中安全复用基础 schema 属性(如字段定义)的方法,避免意外继承 `.xor()`、`.messages()` 等链式配置,核心是使用 `object.keys()` 方法重置 schema 结构。

在使用 Joi 构建复杂验证逻辑时,常需复用已有字段定义(如 a 和 b 的类型、修饰符等),但又不希望继承其附加的约束(如 .xor())或错误消息(.messages())。直接对已链式调用的 schema 调用 .append() 或 .keys() 会保留原有元信息,导致行为不符合预期。

正确做法是:将基础字段定义封装为“纯净”的 Joi.object() 实例(即仅含 keys,无链式修饰),再通过 .keys() 方法扩展新字段。该方法会创建一个全新 schema,仅继承原始对象的键值定义,彻底剥离所有后续链式配置(如 xor、messages、requiredKeys 等)。

以下为推荐实现:

松果AI写作
松果AI写作

专业全能的高效AI写作工具

下载
const Joi = require('@hapi/joi'); // Joi v17+(注意:v17.9.1 及以上)

// ✅ 纯净基础 schema:仅定义字段结构,不添加任何链式约束
const baseSchema = Joi.object({
  a: Joi.string().trim().empty(null, ''),
  b: Joi.string().guid().empty(null),
});

// ✅ 使用 .keys() 复用并扩展字段(自动清除原有 xor/messages)
const extendedSchema = baseSchema.keys({
  c: Joi.string().trim(),
});

// ✅ 分别为不同场景添加独立约束与消息
const firstSchema = baseSchema.xor('a', 'b')
  .messages({
    'object.missing': 'One of "a", "b" is required.',
    'object.xor': 'Only one of "a", "b" is allowed.',
  });

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.',
  });

⚠️ 注意事项:

  • baseSchema.keys({...}) 是关键:它返回一个新 schema 实例,仅保留原始 keys 定义,不会携带 xor、messages、label() 等链式状态;
  • ❌ 错误示例:baseSchema.append({ c: ... }) 会保留原 xor 和 messages,导致二次应用冲突;
  • ❌ 避免在已调用 .xor() 或 .messages() 后再调用 .keys() —— 应始终从“纯净 schema”出发;
  • Joi v17+ 中 Joi.object() 默认返回不可变 schema,每次链式调用均生成新实例,因此 baseSchema 必须是未修饰的原始定义。

总结:Joi 的 object.keys() 不仅用于覆盖字段,更是解耦“结构定义”与“业务约束”的核心工具。将字段定义(schema structure)与验证策略(validation rules)分离,可显著提升 schema 的可维护性与复用性。

相关专题

更多
append用法
append用法

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

343

2023.10.25

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

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

1073

2023.11.14

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

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

175

2025.09.12

html编辑相关教程合集
html编辑相关教程合集

本专题整合了html编辑相关教程合集,阅读专题下面的文章了解更多详细内容。

37

2026.01.21

三角洲入口地址合集
三角洲入口地址合集

本专题整合了三角洲入口地址合集,阅读专题下面的文章了解更多详细内容。

18

2026.01.21

AO3中文版入口地址大全
AO3中文版入口地址大全

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

233

2026.01.21

妖精漫画入口地址合集
妖精漫画入口地址合集

本专题整合了妖精漫画入口地址合集,阅读专题下面的文章了解更多详细内容。

61

2026.01.21

java版本选择建议
java版本选择建议

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

3

2026.01.21

Java编译相关教程合集
Java编译相关教程合集

本专题整合了Java编译相关教程,阅读专题下面的文章了解更多详细内容。

14

2026.01.21

热门下载

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

精品课程

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

共578课时 | 48.8万人学习

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

共12课时 | 1.0万人学习

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

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