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

如何使用Javascript基于自定义Schema验证JSON请求的合法性

JSON请求Schema校验优化方案

方案一:原生JavaScript实现(无第三方依赖)

核心思路

把所有字段的校验规则抽成独立的Schema配置对象,通过递归迭代自动完成所有字段的必填、类型校验,不需要手动编写大量if判断,天然支持多层嵌套、数组结构的校验。

实现代码

首先定义和你业务匹配的校验Schema:

// 校验规则配置,新增/修改字段规则只需调整该对象
const validationSchema = {
  application: {
    type: 'object',
    required: true,
    properties: {
      partnerReferral: {
        type: 'object',
        required: true,
        properties: {
          partnerID: { type: 'string', required: true },
          merchantReferenceID: { type: 'string', required: true }
        }
      },
      businessInformation: {
        type: 'object',
        required: true,
        properties: {
          identity: {
            type: 'array',
            required: true,
            items: {
              type: 'object',
              properties: {
                identifier: { type: 'string', required: true },
                value: { type: 'string', required: true }
              }
            }
          },
          businessType: { type: 'string', required: true },
          classification: {
            type: 'object',
            required: true,
            properties: {
              code: { type: 'string', required: true },
              value: { type: 'string', required: true }
            }
          }
        }
      }
    }
  }
}

然后编写通用递归校验逻辑:

// 错误模板配置
const ERROR_TEMPLATES = {
  REQUIRED_FIELD: (fieldPath) => `${fieldPath} 是必填字段,但请求中未提供`,
  TYPE_MISMATCH: (fieldPath, actualType, expectedType) => `${fieldPath} 预期数据类型为 ${expectedType},实际收到的是 ${actualType}`
}

/**
 * 递归校验方法
 * @param {any} obj 待校验的请求字段值
 * @param {object} schema 对应字段的校验规则
 * @param {string} path 当前字段的完整路径,用于错误提示
 */
function validate(obj, schema, path = '') {
  // 必填字段为空校验
  if (schema.required && (obj == null || obj === '')) {
    return {
      valid: false,
      error: ERROR_TEMPLATES.REQUIRED_FIELD(path || '根请求对象')
    }
  }
  // 非必填字段为空直接跳过后续校验
  if (!schema.required && (obj == null || obj === '')) {
    return { valid: true }
  }
  // 数据类型校验,单独区分数组类型
  const actualType = Array.isArray(obj) ? 'array' : typeof obj
  if (actualType !== schema.type) {
    return {
      valid: false,
      error: ERROR_TEMPLATES.TYPE_MISMATCH(path || '根请求对象', actualType, schema.type)
    }
  }
  // 对象类型递归校验所有子属性
  if (schema.type === 'object' && schema.properties) {
    for (const [prop, subSchema] of Object.entries(schema.properties)) {
      const currentPath = path ? `${path}.${prop}` : prop
      const validateRes = validate(obj[prop], subSchema, currentPath)
      if (!validateRes.valid) return validateRes
    }
  }
  // 数组类型递归校验每一个元素
  if (schema.type === 'array' && schema.items) {
    for (let i = 0; i < obj.length; i++) {
      const currentPath = `${path}[${i}]`
      const validateRes = validate(obj[i], schema.items, currentPath)
      if (!validateRes.valid) return validateRes
    }
  }
  return { valid: true }
}

// 封装为你需要的checkRequest接口
function checkRequest(requestBody) {
  const defaultResponse = {
    validRequest: true,
    responseStatus: "",
    errorTitle: "",
    errorDetail: "",
    errorCode: "",
  }
  const validateRes = validate(requestBody, validationSchema)
  if (!validateRes.valid) {
    return {
      ...defaultResponse,
      validRequest: false,
      responseStatus: "400",
      errorCode: "40001",
      errorTitle: "Bad Request",
      errorDetail: validateRes.error
    }
  }
  return defaultResponse
}

使用示例

const requestBody = {
  application: {
    partnerReferral: {
      partnerID: "mg3e09f8-a8dd-44e6-bb06-55293b799318",
      merchantReferenceID: "mg3e09f8a8dd44e6bb06-55293b799318"
    },
    businessInformation: {
      identity: [
        {
          "identifier": "EMPLOYER_IDENTIFICATION_NUMBER",
          "value": "77-1122333"
        }
      ],
      businessType: "ASSOCIATION",
      classification: {
        "code": "SIC",
        "value": "string"
      }
    }
  }
}
console.log(checkRequest(requestBody))

方案二:第三方库实现(推荐生产环境使用)

如果Workato环境允许引入第三方依赖,推荐使用Ajv,这是JS生态中性能最高、兼容性最好的JSON Schema校验库,支持所有标准JSON Schema特性,不需要自己维护校验逻辑。

实现示例

import Ajv from 'ajv'
const ajv = new Ajv()

// 按标准JSON Schema规范编写校验规则
const schema = {
  type: "object",
  required: ["application"],
  properties: {
    application: {
      type: "object",
      required: ["partnerReferral", "businessInformation"],
      properties: {
        partnerReferral: {
          type: "object",
          required: ["partnerID", "merchantReferenceID"],
          properties: {
            partnerID: { type: "string" },
            merchantReferenceID: { type: "string" }
          }
        }
        // 剩余字段按相同规则补充即可
      }
    }
  }
}

const validate = ajv.compile(schema)

function checkRequest(requestBody) {
  const defaultResponse = {
    validRequest: true,
    responseStatus: "",
    errorTitle: "",
    errorDetail: "",
    errorCode: "",
  }
  const isValid = validate(requestBody)
  if (!isValid) {
    const error = validate.errors[0]
    return {
      ...defaultResponse,
      validRequest: false,
      responseStatus: "400",
      errorCode: "40001",
      errorTitle: "Bad Request",
      errorDetail: `${error.instancePath.slice(1)} ${error.message}`
    }
  }
  return defaultResponse
}

原有代码优化点说明

你原有代码中存在重复逻辑导致的笔误:校验merchant_reference_id字段时,错误提示的字段名仍然写的是partnerID,使用规则配置+自动校验的方式可以完全避免这类问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 19:57:02