JSON Schema
约 1625 字大约 5 分钟
2025-02-24
JSON Schema 是一种声明性语言,用于注释和验证 JSON 文档的结构、约束和数据类型。它提供了一种标准化和定义 JSON 数据预期的方法。
使用
基本使用
最基本的 schema 是一个空白的 JSON 对象,它不约束任何内容,允许任何内容,也不描述任何内容:
{}
通过向架构添加type(type 是验证关键字),可以将约束应用于实例。例如:可以使用 type 关键字将实例限制为对象(object)、数组(array)、字符串(string)、数字(number)、布尔值(boolean)或 null:
{ "type": "string" }
使用 title 和 description 注释
{
"title": "Product",
"description": "A product in the catalog",
"type": "object"
}
使用 $schema
和 $id
schema 关键字
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://example.com/product.schema.json",
"title": "Product",
"description": "A product in the catalog",
"type": "object"
}
$schema
指定该 JSON Schema 所遵循的 JSON Schema 规范版本(标准)。解析器通过这个标准解释这个 Schema。
常见的 JSON Schema 版本:
- Draft 2020-12: "https://json-schema.org/draft/2020-12/schema"
- Draft 2019-09: "https://json-schema.org/draft/2019-09/schema"
- Draft-07: "http://json-schema.org/draft-07/schema#"
- Draft-06: "http://json-schema.org/draft-06/schema#"
- Draft-05: "http://json-schema.org/draft-05/schema#"
注意
不同的 JSON Schema 版本可能有不同的功能和验证规则。例如,Draft 2020-12 支持 unevaluatedProperties,但 Draft 4 不支持。
$id
为该 JSON Schema 分配唯一标识符,通常是一个 URI(URL)。当在多个 JSON Schema 之间引用该 Schema 时,可以使用 $id 作为唯一标识。
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://example.com/main.schema.json",
"type": "object",
"properties": {
"product": {
"$ref": "https://example.com/product.schema.json"
}
}
}
这里的 "$ref": "https://example.com/product.schema.json"
让 主 Schema 直接引用 product.schema.json
,而不用重复定义。
properties
properties 是一个验证关键字。定义属性时,创建的对象,其中每个属性都表示正在验证的 JSON 数据中的一个键。还可以指定需要对象中定义的哪些属性。
{
"properties": {
"price": {
"description": "The price of the product",
"type": "number"
}
}
}
添加 exclusiveMinimum 验证关键字并将值设置为零
{
"properties": {
"price": {
"description": "The price of the product",
"type": "number",
"exclusiveMinimum": 0
}
}
}
将必须的关键字添加到架构末尾的 required 数组之中。如将 price 键添加到数组中:
{
"properties": {
"price": {
"description": "The price of the product",
"type": "number",
"exclusiveMinimum": 0
}
},
"required": ["price"]
}
可选属性
{
"properties": {
"tags": {
"type": "array",
"items": {
"type": "string"
}
}
},
}
要确保数组中至少有一个项,请使用 minItems 验证关键字:
{
"properties": {
"tags": {
"type": "array",
"items": {
"type": "string"
},
"minItems": 1
}
},
}
要确保数组中的每个项目都是唯一的,请使用 uniqueItems 验证关键字并将其设置为 true:
{
"properties": {
"tags": {
"type": "array",
"items": {
"type": "string"
},
"minItems": 1,
"uniqueItems": true
}
},
}
引用 Schema 之外的资源
$ref
和$id
搭配可以用来实现复用。
{
"properties": {
"warehouseLocation": {
"$ref": "https://example.com/warehouseLocation.json"
}
}
}
实例
校验数据是否符合Schema
'''
Author: matiastang
Date: 2025-02-24 17:23:55
LastEditors: matiastang
LastEditTime: 2025-02-24 17:29:17
FilePath: /welfare_lottery_agent/app/utils/jsonschema_vaildate.py
Description: JSON Schema 校验
'''
import jsonschema
from jsonschema import validate
# 定义 JSON Schema
schema = {
"type": "object",
"properties": {
"name": {"type": "string"},
"age": {"type": "integer", "minimum": 0},
"email": {"type": "string", "format": "email"}
},
"required": ["name", "age"]
}
# 需要校验的 JSON 数据
valid_data = {
"name": "Alice",
"age": 25,
"email": "alice@example.com"
}
invalid_data = {
"name": "Bob",
"age": -5 # age 不能为负数
}
# 校验 JSON 数据
def validate_json(data, schema):
try:
validate(instance=data, schema=schema)
print("JSON 数据格式有效")
except jsonschema.exceptions.ValidationError as err:
print("JSON 数据格式无效:", err)
if __name__ == '__main__':
"""
测试 JSON Schema 校验函数
"""
print("校验 valid_data:")
validate_json(valid_data, schema)
print("\n校验 invalid_data:")
validate_json(invalid_data, schema)
校验Schema字符串是否符合标准
'''
Author: matiastang
Date: 2025-02-24 17:23:55
LastEditors: matiastang
LastEditTime: 2025-02-24 17:29:17
FilePath: /welfare_lottery_agent/app/utils/jsonschema_vaildate.py
Description: JSON Schema 校验
'''
import json
import jsonschema
from jsonschema import Draft202012Validator
# 你的 JSON Schema 字符串(示例)
json_schema_str = '''
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"name": { "type": "string" },
"parameters": {
"type": "array",
"items": {
"type": "object",
"properties": {
"name": { "type": "string" },
"type": { "type": "string", "enum": ["string", "integer", "boolean", "array", "object"] }
},
"required": ["name", "type"]
}
},
"returnType": { "type": "string", "enum": ["string", "integer", "boolean", "array", "object", "null"] }
},
"required": ["name", "parameters", "returnType"]
}
'''
# 解析 JSON Schema 字符串
try:
json_schema = json.loads(json_schema_str)
except json.JSONDecodeError as e:
print("JSON 解析错误:", e)
exit()
def validate_schema(schema):
try:
Draft202012Validator.check_schema(schema) # 这里使用最新的 2020-12 规范
print("JSON Schema 定义有效")
except jsonschema.exceptions.SchemaError as err:
print("JSON Schema 定义无效:", err)
if __name__ == '__main__':
"""
测试 JSON Schema 校验函数
"""
validate_schema(json_schema)
总结一下
写几个函数完成上面两种校验。
'''
Author: matiastang
Date: 2025-02-24 17:23:55
LastEditors: matiastang
LastEditTime: 2025-02-24 18:18:57
FilePath: /welfare_lottery_agent/app/utils/jsonschema_vaildate.py
Description: JSON Schema 校验
'''
import json
import traceback
from enum import Enum
from typing import Any
import jsonschema
from jsonschema import (Draft3Validator, Draft4Validator, Draft6Validator, Draft7Validator, Draft201909Validator,
Draft202012Validator, validate)
from loguru import logger
class DraftVersions(Enum):
"""Draft 版本"""
DRAFT_3 = 'Draft3'
DRAFT_4 = 'Draft4'
DRAFT_6 = 'Draft6'
DRAFT_7 = 'Draft7'
DRAFT_201909 = 'Draft201909'
DRAFT_202012 = 'Draft202012'
def validate_json_schema(data: object, schema: Any) -> bool:
"""
校验 JSON 数据是否符合 JSON Schema
Args:
data (object): 数据
schema (Any): 规范
Returns:
bool: 是否符合规范
"""
try:
validate(instance=data, schema=schema)
return True
except jsonschema.exceptions.ValidationError as err:
logger.info("JSON Schema 定义无效:", str(err))
err_trace_msg = traceback.format_exc()
logger.error(err_trace_msg)
return False
def validate_json_schema_str(data: str, schema: Any) -> bool:
"""
校验 str 数据是否符合 JSON Schema
Args:
data (str): 字符串数据
schema (Any): 规范
Returns:
bool: 是否符合规范
"""
try:
json_data = json.loads(data)
return validate_json_schema(json_data, schema)
except json.JSONDecodeError as e:
logger.info("JSON 解析错误:", str(e))
err_trace_msg = traceback.format_exc()
logger.error(err_trace_msg)
return False
def validate_schema(schema: Any, *, draft_version: DraftVersions = DraftVersions.DRAFT_202012) -> bool:
"""
校验 JSON Schema 是否符合 JSON Schema 规范
Args:
json_schema (Any): JSON Schema
draft_version (DraftVersions, optional): JSON Schema 版本. Defaults to DraftVersions.DRAFT_202012.
Returns:
bool: 是否符合规范
"""
try:
if draft_version == DraftVersions.DRAFT_3:
Draft3Validator.check_schema(schema)
elif draft_version == DraftVersions.DRAFT_4:
Draft4Validator.check_schema(schema)
elif draft_version == DraftVersions.DRAFT_6:
Draft6Validator.check_schema(schema)
elif draft_version == DraftVersions.DRAFT_7:
Draft7Validator.check_schema(schema)
elif draft_version == DraftVersions.DRAFT_201909:
Draft201909Validator.check_schema(schema)
else:
Draft202012Validator.check_schema(schema)
return True
except jsonschema.exceptions.SchemaError as err:
logger.info("JSON Schema 定义无效:", str(err))
err_trace_msg = traceback.format_exc()
logger.error(err_trace_msg)
return False
def validate_schema_str(json_schema_str: str, *, draft_version: DraftVersions = DraftVersions.DRAFT_202012) -> bool:
"""
校验 JSON Schema 字符串是否符合 JSON Schema 规范
Args:
json_schema_str (str): JSON Schema 字符串
draft_version (DraftVersions, optional): JSON Schema 版本. Defaults to DraftVersions.DRAFT_202012.
Returns:
bool: 是否符合规范
"""
try:
json_schema = json.loads(json_schema_str)
return validate_schema(json_schema, draft_version=draft_version)
except json.JSONDecodeError as e:
logger.info("JSON 解析错误:", str(e))
err_trace_msg = traceback.format_exc()
logger.error(err_trace_msg)
return False
if __name__ == '__main__':
"""
测试 JSON Schema 校验函数
python3 -m app.utils.jsonschema_vaildate
"""
# 定义 JSON Schema
schema = {
"type": "object",
"properties": {
"name": {"type": "string"},
"age": {"type": "integer", "minimum": 0},
"email": {"type": "string", "format": "email"}
},
"required": ["name", "age"]
}
# 需要校验的 JSON 数据
valid_data = {
"name": "Alice",
"age": 25,
"email": "alice@example.com"
}
valid_status = validate_json_schema(valid_data, schema)
print(f"{valid_data}\n{'符合' if valid_status else '不符合'}\n{schema}规范\n")
valid_data_str = json.dumps(valid_data)
valid_status = validate_json_schema_str(valid_data_str, schema)
print(f"{valid_data_str}\n{'是' if valid_status else '不是'}\n符合{schema}规范的字符串\n")
# 你的 JSON Schema 字符串(示例)
json_schema_str = '''
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"name": { "type": "string" },
"parameters": {
"type": "array",
"items": {
"type": "object",
"properties": {
"name": { "type": "string" },
"type": { "type": "string", "enum": ["string", "integer", "boolean", "array", "object"] }
},
"required": ["name", "type"]
}
},
"returnType": { "type": "string", "enum": ["string", "integer", "boolean", "array", "object", "null"] }
},
"required": ["name", "parameters", "returnType"]
}
'''
validate_schema_str(json_schema_str)
print(f"{json_schema_str}\n{'是' if valid_status else '不是'}一个有效的 JSON Schema 规范")
其他
GitHub json-schema-vocabularies,一个收集已知第三方 JSON Schema 词汇的存储库。