You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JSON Schema与AJV+JsonForms如何实现校验警告而非阻断性错误

可行实现方案

核心思路

JSON Schema原生不支持校验分级能力,我们通过AJV自定义扩展字段+前后端统一处理逻辑实现「建议必填/警告级校验」能力,完全兼容现有通用架构,不会影响原有强制校验逻辑。

步骤1:AJV扩展自定义警告级校验关键词

给AJV注册x-recommended-required自定义关键词,用于标记建议必填的字段,校验时仅生成警告标记,不触发校验失败,该扩展代码前后端统一引用即可保证规则一致:

// 通用AJV初始化扩展代码
ajv = createAjv({
  schemaId: 'auto',
  allErrors: true,
  jsonPointers: true,
  errorDataPath: 'property',
});

// 注册建议必填自定义关键词
ajv.addKeyword({
  keyword: 'x-recommended-required',
  type: 'object',
  schemaType: 'array',
  errors: true,
  compile: (schema) => {
    return (data) => {
      const missingFields = schema.filter(field => data?.[field] === undefined || data?.[field] === null);
      if (missingFields.length > 0) {
        const warnErrors = missingFields.map(field => ({
          keyword: 'x-recommended-required',
          dataPath: `/${field}`,
          message: `字段${field}为建议必填项,建议填写后提交`,
          params: { missingProperty: field },
          isWarning: true // 核心标记,用于区分警告和强制错误
        }));
        // 挂载警告信息到AJV错误列表,不影响校验结果
        ajv.errors = ajv.errors ? [...ajv.errors, ...warnErrors] : warnErrors;
      }
      // 始终返回true,不会触发校验失败
      return true;
    };
  }
});

步骤2:修改数据Schema适配建议必填需求

在需要的对象节点添加x-recommended-required配置,填写建议必填的字段名即可,不需要修改其他原有配置,示例如下:

{
  "type": "object",
  "properties": {
    "group1": {
      "type": "object",
      "properties": {
        "level1": { "type": "integer", "enum": [0, 1, 2, 3, 4, 5, 6] },
        "level2": { "type": "integer", "enum": [0, 1, 2, 3, 4, 5, 6] },
        "level3": { "type": "integer", "enum": [0, 1, 2, 3, 4, 5, 6] },
        "level4": { "type": "integer", "enum": [0, 1, 2, 3, 4, 5, 6] }
      },
      "additionalProperties": false,
      "required": [],
      // 新增配置:group1下level1、level2为建议必填项
      "x-recommended-required": ["level1", "level2"]
    },
    "group2": {
      "type": "object",
      "properties": {
        "level1": { "type": "integer", "enum": [0, 1, 2, 3, 4, 5, 6] },
        "level2": { "type": "integer", "enum": [0, 1, 2, 3, 4, 5, 6] },
        "level3": { "type": "integer", "enum": [0, 1, 2, 3, 4, 5, 6] },
        "level4": { "type": "integer", "enum": [0, 1, 2, 3, 4, 5, 6] }
      },
      "additionalProperties": false,
      "required": []
    }
  }
}

步骤3:JsonForms前端逻辑适配

  • 自定义校验结果渲染:修改JsonForms的错误渲染逻辑,判断错误对象携带isWarning: true标记时,用黄色警告样式展示,不要标记为字段错误
  • 提交逻辑调整:用户点击提交时,先执行校验,拆分校验结果为「强制错误」和「警告错误」两类
    • 存在强制错误:阻止提交,正常提示用户修正
    • 无强制错误、仅存在警告错误:弹出确认模态框,告知用户有未填写的建议项,用户确认后即可正常提交
    • 无任何错误:直接提交

步骤4:NestJS后端逻辑适配

后端二次校验时,同样拆分校验结果,只要不存在非警告类的强制错误,即可放行数据入库,警告信息可按需存入操作日志留痕,不影响主流程。

方案优势

  • 完全兼容现有通用架构,不需要为每个表单写自定义代码,新增建议必填表单仅需修改Schema配置即可
  • 前后端校验逻辑完全统一,不会出现前后端规则不一致的问题
  • 不侵入原有强制校验逻辑,两类校验规则互不干扰

备选方案:双Schema校验

如果不想扩展AJV关键词,也可以为每个需要警告的表单维护两套Schema:

  1. 强制校验Schema:用于前后端提交放行判断,校验通过即可入库
  2. 警告校验Schema:仅用于生成警告提示,校验结果不影响提交流程
    该方案好处是不需要修改AJV初始化逻辑,缺点是同一个表单需要维护两套Schema,维护成本略高。

内容的提问来源于stack exchange,提问作者Eds Keizer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 00:06:05