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

如何在JSON Schema中根据Task Type引用对应子Schema验证数据?

根据Task的Type字段动态验证Properties的JSON Schema实现方案

问题描述

我正在编写JSON Schema以验证数据,但遇到实现需求的问题:需要根据Task的type字段,对properties字段做差异化验证,同时抽离Task的公共属性到统一Schema中。

数据示例

{
    "orderName": "CoreCapital",
    "orderType": "Capital",
    "requestId": "Generated ID",
    "tasks": [
        {
            "type": "User",
            "taskId": 1,
            "name": "Level-1",
            "executor": "Marine",
            "description": "Get Details",
            "properties": {
                "stateId": 123,
                "params": [
                    "parameter1",
                    "parameter2"
                ]
            }
        },
        {
            "type": "Manager",
            "taskId": 2,
            "name": "Level-2",
            "executor": "Shipping",
            "description": "Shipping Details",
            "properties": {
                "id": 2345,
                "baseId": "Shipping-23",
                "method": "POST",
                "params": {
                    "Id": "1234",
                    "tag": "Fire"
                },
                "locale": {
                    "USA": "tag-1",
                    "Canada": "tag-2",
                    "Europe": "tag-3"
                }
            }
        },
        {
            "type": "Director",
            "taskId": 3,
            "name": "Level-3",
            "executor": "Transport",
            "description": "Transport Details",
            "properties": {
                "name": "Water-resource",
                "payload": "truck details",
                "Size": "40 ton",
                "State": {
                    "CA": "tag-4",
                    "AR": "tag-5",
                    "MS": "tag-6"
                }
            }
        }
    ]
}

(注:已修正原数据中的语法错误,不影响Schema验证逻辑)

需求

  • 对每个Task做差异化验证:type为User时,properties符合UserProperties子Schema;type为Manager时符合ManagerProperties;type为Director时符合DirectorProperties。
  • 抽离Task的公共属性(如taskId、name等)到统一Schema中。

解决方案

使用JSON Schema的if/then条件验证特性,结合allOf和oneOf来实现逻辑,以下是完整的Schema示例:

{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "type": "object",
  "properties": {
    "orderName": { "type": "string" },
    "orderType": { "type": "string" },
    "requestId": { "type": "string" },
    "tasks": {
      "type": "array",
      "items": {
        "allOf": [
          // 公共Task属性验证
          {
            "type": "object",
            "required": ["type", "taskId", "name", "executor", "description", "properties"],
            "properties": {
              "type": { "enum": ["User", "Manager", "Director"] },
              "taskId": { "type": "integer" },
              "name": { "type": "string" },
              "executor": { "type": "string" },
              "description": { "type": "string" }
            }
          },
          // 按type字段匹配对应的properties验证规则
          {
            "oneOf": [
              {
                "if": { "properties": { "type": { "const": "User" } } },
                "then": { "properties": { "properties": { "$ref": "#/$defs/UserProperties" } } }
              },
              {
                "if": { "properties": { "type": { "const": "Manager" } } },
                "then": { "properties": { "properties": { "$ref": "#/$defs/ManagerProperties" } } }
              },
              {
                "if": { "properties": { "type": { "const": "Director" } } },
                "then": { "properties": { "properties": { "$ref": "#/$defs/DirectorProperties" } } }
              }
            ]
          }
        ]
      }
    }
  },
  "required": ["orderName", "orderType", "requestId", "tasks"],
  "$defs": {
    "UserProperties": {
      "type": "object",
      "required": ["stateId", "params"],
      "properties": {
        "stateId": { "type": "integer" },
        "params": { "type": "array", "items": { "type": "string" } }
      }
    },
    "ManagerProperties": {
      "type": "object",
      "required": ["id", "baseId", "method", "params", "locale"],
      "properties": {
        "id": { "type": "integer" },
        "baseId": { "type": "string" },
        "method": { "type": "string", "enum": ["POST"] },
        "params": {
          "type": "object",
          "required": ["Id", "tag"],
          "properties": {
            "Id": { "type": "string" },
            "tag": { "type": "string" }
          }
        },
        "locale": {
          "type": "object",
          "patternProperties": {
            "^(USA|Canada|Europe)$": { "type": "string" }
          },
          "additionalProperties": false
        }
      }
    },
    "DirectorProperties": {
      "type": "object",
      "required": ["name", "payload", "Size", "State"],
      "properties": {
        "name": { "type": "string" },
        "payload": { "type": "string" },
        "Size": { "type": "string" },
        "State": {
          "type": "object",
          "patternProperties": {
            "^(CA|AR|MS)$": { "type": "string" }
          },
          "additionalProperties": false
        }
      }
    }
  }
}

关键逻辑说明

  • 公共属性复用:通过allOf将公共Task属性Schema与条件验证规则组合,确保所有Task都满足基础字段要求。
  • 条件验证:使用if/then搭配const精准匹配type值,当type符合指定值时,强制properties字段匹配对应的子Schema。
  • 分支唯一性:用oneOf包裹三个条件分支,确保每个Task只会触发其中一组验证规则,避免冲突。
  • 子Schema管理:所有Properties子Schema定义在$defs(Draft 07及以上版本推荐)中,提升可读性和维护性。

常见问题排查

如果验证器未按预期工作,可检查以下几点:

  • 验证器是否支持JSON Schema Draft 07及以上版本:if/then和const是Draft 07新增特性,需使用支持该版本的验证器(如Ajv v6+)。
  • $ref路径是否正确:确保引用路径与子Schema的定义位置一致(如用#/$defs/xxx而非旧版的#/definitions/xxx)。
  • 公共Schema是否限制了properties字段:公共属性Schema中不要对properties字段做额外限制,避免覆盖条件规则中的定义。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 19:40:26