如何避免jsonschema解析$ref引用时向对应URI发起GET请求
解决方案
要遵循JSON Schema规范使用$ref同时避免远程请求,你需要提前将本地定义的schema注册到jsonschema的解析器缓存中,让解析器遇到对应的$id时直接读取本地资源,而非发起远程请求。
完整实现代码
from jsonschema import validate, RefResolver # 保留原有schema定义 point_schema = { "$id": "https://example.com/schemas/point", "type": "object", "properties": {"x": {"type": "number"}, "y": {"type": "number"}}, "required": ["x", "y"], } polygon_schema = { "$id": "https://example.com/schemas/polygon", "type": "array", "items": {"$ref": "https://example.com/schemas/point"}, } a_polygon = [{'x': 1, 'y': 2}, {'x': 3, 'y': 4}, {'x': 1, 'y': 2}] # 构建本地schema映射:key为schema的$id,value为对应schema对象 local_schema_store = { point_schema["$id"]: point_schema, polygon_schema["$id"]: polygon_schema } # 创建自定义解析器,传入本地schema存储 resolver = RefResolver( base_uri=polygon_schema["$id"], referrer=polygon_schema, store=local_schema_store ) # 校验时传入自定义解析器 validate( instance=a_polygon, schema=polygon_schema, resolver=resolver )
方案说明
- 上述实现完全遵循JSON Schema的
$ref规范,没有直接拼接字典 - 解析器遇到
$ref对应的URI时,会优先查找local_schema_store中的本地schema,不会发起任何远程GET请求 - 如果有更多本地schema,只需要添加到
local_schema_store字典中即可
替代简化方案
如果不需要拆分schema为独立的字典,也可以将公共schema放到当前schema的$defs字段中,使用本地相对引用,无需自定义解析器:
polygon_schema = { "$id": "https://example.com/schemas/polygon", "type": "array", "items": {"$ref": "#/$defs/point"}, "$defs": { "point": { "type": "object", "properties": {"x": {"type": "number"}, "y": {"type": "number"}}, "required": ["x", "y"], } } } a_polygon = [{'x': 1, 'y': 2}, {'x': 3, 'y': 4}, {'x': 1, 'y': 2}] validate(instance=a_polygon, schema=polygon_schema)
这种方式的$ref指向当前schema内部的定义,天然不会触发远程请求,同样符合JSON Schema规范。
内容的提问来源于stack exchange,提问作者Flame_Phoenix
相关产品推荐
相关产品推荐

