JSON Schema高级教程:基于嵌套属性的条件必填校验

json schema高级教程:基于嵌套属性的条件必填校验

JSON Schema作为一种强大的数据结构描述语言,广泛应用于API请求体、配置文件等场景的数据验证。然而,在面对复杂的业务逻辑时,例如根据某个字段的值来动态地改变其他字段的必填性,尤其是当这些字段处于不同层级时,往往会遇到挑战。本文将详细阐述如何利用JSON Schema的条件关键字,实现基于嵌套属性的顶层属性条件必填校验。

问题场景:基于订单类型的商品列表必填

设想一个订单验证场景,我们有一个Order对象,其中包含attributes嵌套对象,而attributes中又有一个order_type字段。我们的需求是:

当attributes.order_type的值为”ORDER”时,顶层的items属性必须存在且非空。对于order_type的其他值(如”TRANSFER”、”WITHDRAWAL”等),items属性是可选的。

最初的尝试可能倾向于将条件逻辑放置在attributes属性的定义内部,例如在attributes的allOf数组中添加对items的required校验。然而,这种做法是无效的。JSON Schema中required关键字的作用域是其所在的当前JSON对象。这意味着,如果if/then块位于attributes的定义内部,其then块中的required只能作用于attributes自身的子属性,而无法影响到与attributes同级的items属性。

JSON Schema条件逻辑:if、then与allOf

为了解决这类问题,我们需要借助JSON Schema提供的条件关键字:

if: 定义一个子模式作为条件。如果数据实例符合if子模式,则应用then子模式。then: 当if条件满足时,需要应用的数据模式。allOf: 用于组合多个子模式。数据实例必须同时满足allOf数组中的所有子模式才能通过验证。

关键在于,if/then块的放置位置决定了其作用域。要使条件逻辑能够影响到与attributes同级的items属性,if/then块必须放置在顶层(根级别),与properties和required关键字处于同一层级。

博思AIPPT 博思AIPPT

博思AIPPT来了,海量PPT模板任选,零基础也能快速用AI制作PPT。

博思AIPPT 117 查看详情 博思AIPPT

解决方案:在根级别应用条件逻辑

正确的做法是,在主Schema的根级别添加一个allOf块,并在其中定义我们的条件逻辑。这个if条件需要能够“看到”并判断嵌套的attributes.order_type字段。

以下是实现上述需求的完整JSON Schema:

{  "$schema": "http://json-schema.org/draft-07/schema#",  "$id": "http://json-schema.org/draft-07/schema#",  "title": "Validaciones sobre el esquema Order",  "type": "object",  "properties": {    "warehouse_id": {      "type": [        "string"      ]    },    "operation_type": {      "type": [        "string"      ]    },    "order_id": {      "type": [        "number"      ]    },    "items": {      "type": [        "array"      ],      "minItems": 1,      "items": {        "type": [          "object"        ],        "properties": {          "sku": {            "type": [              "string"            ],            "minLength": 1,            "maxLength": 50          },          "quantity": {            "type": [              "integer"            ],            "minimum": 1          }        },        "required": [          "sku",          "quantity"        ],        "additionalProperties": false      }    },    "attributes": {      "type": [        "object"      ],      "properties": {        "order_type": {          "type": [            "string"          ],          "enum": [            "ORDER",            "TRANSFER",            "WITHDRAWAL",            "DISPOSAL",            "FRESH"          ]        },        "etd": {          "type": [            "string"          ],          "pattern": "^(\d{4})-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])(?:T)(0[0-9]|1[0-9]|2[0-3]):(0[0-9]|1[0-9]|1[0-9]|2[0-9]|3[0-9]|4[0-9]|5[0-9]):(0[0-9]|1[0-9]|2[0-9]|3[0-9]|4[0-9]|5[0-9])(?:Z)$"        },        "volume": {          "type": [            "integer", "null"          ],          "minimum": 0        },        "typology": true      },      "required": [        "order_type"      ],      "allOf": [        {          "if": {            "properties": {              "order_type": {                "const": "ORDER"              }            },            "required": [              "order_type"            ]          },          "then": {            "properties": {              "order_type": true,              "etd": true,              "volume": true,              "typology": {                "type": [                  "string", "null"                ],                "enum": [                  "CONVEYABLE",                  "NON_CONVEYABLE"                ]              }            },            "required": [              "order_type",              "etd"            ],            "additionalProperties": false          }        },        {          "if": {            "properties": {              "order_type": {                "const": "TRANSFER"              }            },            "required": [              "order_type"            ]          },          "then": {            "properties": {              "order_type": true,              "etd": true,              "volume": true            },            "required": [              "order_type",              "etd"            ],            "additionalProperties": false          }        },        {          "if": {            "properties": {              "order_type": {                "const": "WITHDRAWAL"              }            },            "required": [              "order_type"            ]          },          "then": {            "properties": {              "order_type": true,              "etd": true,              "volume": true            },            "required": [              "order_type",              "etd"            ],            "additionalProperties": false          }        },        {          "if": {            "properties": {              "order_type": {                "const": "DISPOSAL"              }            },            "required": [              "order_type"            ]          },          "then": {            "properties": {              "order_type": true,              "etd": true,              "volume": true            },            "required": [              "order_type",              "etd"            ],            "additionalProperties": false          }        }      ]    }  },  "required": [    "warehouse_id",    "operation_type",    "attributes"  ],  "additionalProperties": false,  "allOf": [    {      "if": {        "properties": {          "attributes": {            "properties": {              "order_type": { "const": "ORDER" }            },            "required": ["order_type"]          }        },        "required": ["attributes"]      },      "then": {        "required": ["items"]      }    }  ]}

核心Schema解析

让我们聚焦于解决问题的关键部分——位于根级别的allOf块:

  "allOf": [    {      "if": {        "properties": { // 匹配当前(根)对象的属性          "attributes": { // 检查名为 "attributes" 的属性            "properties": {              "order_type": { "const": "ORDER" } // 进一步检查 "attributes" 内部的 "order_type" 属性,其值必须是 "ORDER"            },            "required": ["order_type"] // 确保 "attributes" 对象中包含 "order_type"          }        },        "required": ["attributes"] // 确保根对象中包含 "attributes" 属性      },

以上就是JSON Schema高级教程:基于嵌套属性的条件必填校验的详细内容,更多请关注创想鸟其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/959240.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2025年12月1日 18:33:11
下一篇 2025年12月1日 18:33:32

相关推荐

发表回复

登录后才能评论
关注微信