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 等)。

以下为推荐实现:

Mapify
Mapify

Mapify是由Xmind推出的AI思维导图生成工具,原名ChatMind

下载
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的更多内容,可以阅读本专题下面的文章。

1068

2023.11.14

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

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

172

2025.09.12

c++主流开发框架汇总
c++主流开发框架汇总

本专题整合了c++开发框架推荐,阅读专题下面的文章了解更多详细内容。

3

2026.01.09

c++框架学习教程汇总
c++框架学习教程汇总

本专题整合了c++框架学习教程汇总,阅读专题下面的文章了解更多详细内容。

7

2026.01.09

学python好用的网站推荐
学python好用的网站推荐

本专题整合了python学习教程汇总,阅读专题下面的文章了解更多详细内容。

10

2026.01.09

学python网站汇总
学python网站汇总

本专题整合了学python网站汇总,阅读专题下面的文章了解更多详细内容。

1

2026.01.09

python学习网站
python学习网站

本专题整合了python学习相关推荐汇总,阅读专题下面的文章了解更多详细内容。

4

2026.01.09

俄罗斯手机浏览器地址汇总
俄罗斯手机浏览器地址汇总

汇总俄罗斯Yandex手机浏览器官方网址入口,涵盖国际版与俄语版,适配移动端访问,一键直达搜索、地图、新闻等核心服务。

9

2026.01.09

热门下载

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

精品课程

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

共578课时 | 43.9万人学习

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

共12课时 | 1.0万人学习

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

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