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

如何为AJV Schema添加自定义验证函数(无需新增关键字)

无需新增Schema关键字,给AJV添加自定义日期范围校验

要实现date_fr始终小于date_to的校验需求,且不修改原有Schema、不添加额外关键字,可通过包装AJV标准验证函数的方式实现,具体步骤如下:

1. 初始化AJV实例

创建AJV实例并开启全错误返回,便于调试所有校验问题:

const Ajv = require('ajv');
const ajv = new Ajv({ allErrors: true });

2. 编写日期范围校验逻辑

实现单条日期记录的校验函数,处理date_to可选的业务场景:

function checkDateRange(dateItem) {
  // date_to为可选字段,不存在时直接通过校验
  if (!dateItem.date_to) return true;
  // 若date_fr为空,直接判定不合法(业务允许可选时可调整此逻辑)
  if (!dateItem.date_fr) return false;

  const dateFrom = new Date(dateItem.date_fr);
  const dateTo = new Date(dateItem.date_to);

  // 二次校验日期合法性(避免格式合法但实际无效的日期值)
  if (isNaN(dateFrom.getTime()) || isNaN(dateTo.getTime())) {
    return false;
  }

  // 核心校验规则:date_fr必须早于date_to
  return dateFrom < dateTo;
}

3. 整合标准校验与自定义校验

先编译原有Schema得到标准验证函数,再包装一层,在标准校验通过后执行自定义日期校验,并将自定义错误信息整合到AJV的错误集合中:

// 编译原有Schema,生成标准验证函数
const validateStandard = ajv.compile(mySchema);

// 包装验证函数,整合自定义校验逻辑
function validate(data) {
  // 先执行标准Schema校验,不通过直接返回结果
  const isStandardValid = validateStandard(data);
  if (!isStandardValid) return false;

  // 遍历所有数据节点,执行自定义日期范围校验
  data.forEach((listItem, listIndex) => {
    if (listItem.my_list_itm) {
      listItem.my_list_itm.forEach((dateItem, dateIndex) => {
        if (!checkDateRange(dateItem)) {
          // 将自定义错误添加到AJV错误列表,保持错误格式一致
          validateStandard.errors.push({
            instancePath: `/${listIndex}/my_list_itm/${dateIndex}`,
            keyword: 'customDateRange',
            message: 'date_fr必须早于date_to',
            params: { keyword: 'customDateRange' }
          });
        }
      });
    }
  });

  // 若存在自定义错误,返回false;否则返回true
  return validateStandard.errors.length === 0;
}

使用示例

调用包装后的validate函数即可完成完整校验:

const testData = [
  {
    my_list_key: 'test1',
    my_list_itm: [
      { date_fr: '2024-01-01', date_to: '2024-01-02' }, // 合法
      { date_fr: '2024-02-01', date_to: '2024-01-01' }  // 不合法
    ]
  }
];

const isValid = validate(testData);
if (!isValid) {
  console.error('校验失败:', validateStandard.errors);
}

这种方案完全保留原有Schema结构,未添加任何额外关键字,同时将自定义校验与AJV标准校验深度整合,错误信息格式统一,便于前端或服务端处理。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 22:55:28