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

如何验证扁平化JSON键?基于JSON Schema的REST查询校验问询

验证扁平化JSON查询键的通用方案

核心问题拆解

你需要验证REST查询中扁平化键(如emp_meta.manages)是否符合给定JSON Schema的结构,难点在于处理oneOf分支(比如emp_meta对应两种员工类型,仅Manager有manages字段),以及关联字段的合法性校验。


方案一:预编译Schema的合法路径映射

先把Schema中所有可能的合法扁平化路径提取出来,同时记录每个路径对应的前置条件,后续直接用这个映射校验查询键。

实现步骤

  1. 递归遍历Schema收集路径:处理$ref和oneOf分支,把所有嵌套字段展开为扁平化路径,同时记录路径生效的条件(比如emp_meta.manages仅在emp_category=MANAGER时合法)。
  2. 路径与条件关联:针对oneOf分支中的枚举关联(比如emp_category的枚举值对应emp_meta的不同类型),把这类关联作为路径的前置条件存入映射。

伪代码示例

def collect_valid_paths(schema, current_path="", conditions=None):
    valid_paths = {}
    conditions = conditions or []

    # 处理引用类型
    if "$ref" in schema:
        ref_parts = schema["$ref"].lstrip("#/").split("/")
        ref_schema = schema
        for part in ref_parts:
            ref_schema = ref_schema[part]
        return collect_valid_paths(ref_schema, current_path, conditions.copy())

    # 处理oneOf分支
    if "oneOf" in schema:
        for sub_schema in schema["oneOf"]:
            # 处理枚举分支(如emp_category的可选值)
            if "enum" in sub_schema:
                enum_vals = sub_schema["enum"]
                new_conds = conditions + [(current_path, enum_vals)]
                continue
            # 处理对象分支(如emp_meta的两种员工类型)
            sub_paths = collect_valid_paths(sub_schema, current_path, conditions.copy())
            for path, conds in sub_paths.items():
                if path not in valid_paths:
                    valid_paths[path] = []
                valid_paths[path].extend(conds)
        return valid_paths

    # 处理对象类型的属性
    if schema.get("type") == "object" and "properties" in schema:
        for prop, prop_schema in schema["properties"].items():
            new_path = f"{current_path}.{prop}" if current_path else prop
            sub_paths = collect_valid_paths(prop_schema, new_path, conditions.copy())
            for path, conds in sub_paths.items():
                if path not in valid_paths:
                    valid_paths[path] = []
                valid_paths[path].extend(conds)
        return valid_paths

    # 非对象类型,返回当前路径
    return {current_path: conditions}

# 生成合法路径映射
employee_schema = {...} # 你的Employee Schema
valid_path_map = collect_valid_paths(employee_schema)

查询校验逻辑

拿到查询中的扁平化键后:

  1. 检查键是否存在于valid_path_map中,不存在则直接返回非法。
  2. 检查该键对应的前置条件是否在查询中满足。比如查询里有emp_meta.manages,则必须同时存在emp_category=MANAGER的条件,否则判定为非法。

方案二:改用结构化查询语法

如果扁平化键的校验逻辑过于复杂,可以直接让查询载荷的结构与Schema对齐,避免扁平化解析的麻烦。

示例结构化查询

{
  "employee": {
    "AND": [
      {"emp_category": "MANAGER"},
      {"emp_meta": {"department": "R&D"}},
      {"emp_meta": {"manages": "John*"}}
    ]
  }
}

校验优势

  • 直接复用原Schema的验证逻辑:针对每个查询条件,生成对应的Schema片段进行校验(比如用Manager类型的Schema校验{"emp_meta": {"manages": "John*"}})。
  • 无需处理扁平化键的解析,条件关联逻辑更直观(比如emp_meta的结构自动对应emp_category指定的类型)。

关于必填字段的澄清

Schema中的必填字段是针对数据对象的约束,而非查询条件。查询中可以使用任何合法存在的字段(无论是否必填),不需要强制包含必填字段。比如你可以只查询emp_meta.department,无需同时指定emp_meta.id。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 09:01:02