0

0

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

碧海醫心

碧海醫心

发布时间:2026-01-05 18:14:45

|

385人浏览过

|

来源于php中文网

原创

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

本文介绍在 joi 中高效复用已有对象 schema 字段(如 `a`、`b`)的方法:通过 `schema.keys()` 动态扩展属性,避免误继承 `.xor()`、`.messages()` 等顶层配置,实现清晰、可维护的 schema 分层设计。

在使用 Joi 构建复杂数据校验逻辑时,常需复用基础字段定义(如公共字段 a、b),但又不希望连带继承其组合约束(如 .xor())或错误消息(.messages())。直接链式调用 .append() 或 .keys() 在已应用顶层规则的 schema 上会保留原有约束,导致行为不符合预期。

正确做法是:将基础字段定义封装为“纯净”的 Joi.object() 实例(不附加 .xor() 或 .messages()),再通过 .keys() 方法进行扩展。该方法仅合并键值定义,完全忽略原 schema 的校验元信息(如 xor、and、messages、label 等),确保干净复用。

以下是推荐实现:

知元AI
知元AI

AI智能语音聊天 对讲问答 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),
});

// ✅ 复用字段并新增 'c',生成新 object schema
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.append({ c: ... }) 或 baseSchema.keys({...}) 在已调用 .xor() 的 schema 上执行 —— 此时 baseSchema 已携带组合规则,.keys() 仍会保留它,导致 secondSchema 意外继承 xor('a','b');✅ 正确前提:baseSchema 必须是“未增强”的原始对象 schema(即仅 Joi.object({ ... }) 调用后立即保存,未链式添加 .xor()/.messages());? 进阶提示:可将 baseSchema 命名为 baseFields 以语义化其职责,提升代码可读性;? Joi v17+ 中 Joi.object().keys() 是标准且稳定 API;若使用旧版(v16 及以下),需改用 Joi.object().concat(Joi.object({...})),但语义稍弱且不推荐。

总结:Joi 的 Schema 设计应遵循「结构分离、约束后置」原则——字段定义(structure)与业务规则(validation logic)解耦。借助 .keys() 复用字段,再独立绑定 .xor()、.or()、.messages() 等,既能保障复用性,又能精准控制每层 Schema 的行为边界。

相关专题

更多
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的相关内容,阅读专题下面的文章了解更多详细内容。

171

2025.09.12

C++ 高性能计算与并行编程
C++ 高性能计算与并行编程

本专题专注于 C++ 在高性能计算(HPC)与并行编程中的应用,涵盖多线程、并发数据处理、OpenMP、MPI、GPU加速等技术。通过实际案例,帮助开发者掌握 如何利用 C++ 进行大规模数据计算和并行处理,提高程序的执行效率,适应高性能计算与数据密集型应用场景。

4

2026.01.08

C++ 高性能计算与并行编程
C++ 高性能计算与并行编程

本专题专注于 C++ 在高性能计算(HPC)与并行编程中的应用,涵盖多线程、并发数据处理、OpenMP、MPI、GPU加速等技术。通过实际案例,帮助开发者掌握 如何利用 C++ 进行大规模数据计算和并行处理,提高程序的执行效率,适应高性能计算与数据密集型应用场景。

0

2026.01.08

PPT动态图表制作教程大全
PPT动态图表制作教程大全

本专题整合了PPT动态图表制作相关教程,阅读专题下面的文章了解更多详细内容。

36

2026.01.07

c++ Libcurl用法详解
c++ Libcurl用法详解

本专题整合了c++ Libcurl用法详解,阅读专题下面的文章了解更多详细内容。

0

2026.01.07

c++ Libcurl用法大全
c++ Libcurl用法大全

本专题整合了c++ Libcurl用法详解,阅读专题下面的文章了解更多详细内容。

0

2026.01.07

C++ vector用法汇总
C++ vector用法汇总

本专题整合了C++中vector的用法大全,阅读专题下面的文章了解更多详细内容。

2

2026.01.07

热门下载

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

精品课程

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

共578课时 | 43.3万人学习

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

共12课时 | 0.9万人学习

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

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