alltools.one
JSON
2025-07-09
10 min
alltools.one Team
JSONSchemaValidationAPIData Quality

JSON Schema 验证:权威指南

JSON Schema 是用于注释和验证 JSON 文档的词汇表。它为你的数据提供了一份契约——定义数据应该是什么形状、哪些类型是可接受的、哪些字段是必需的。如果你使用 API、配置文件或任何结构化数据,JSON Schema 是你工具箱中的必备工具。

为什么使用 JSON Schema?

没有验证,JSON 数据就是一个未知数。你可能收到字符串类型的 age 字段、缺失的 email,或格式错误的日期。JSON Schema 在边界处捕获这些问题,防止错误数据在系统中传播。

主要优势

  • API 契约执行:自动验证请求和响应体
  • 文档化:Schema 作为数据结构的活文档
  • 代码生成:工具可以从 JSON Schema 生成类型、表单和数据库模式
  • 测试:根据 Schema 验证测试夹具和模拟数据

基本 Schema 结构

每个 JSON Schema 从几个标准属性开始:

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://example.com/user.schema.json",
  "title": "User",
  "description": "A registered user in the system",
  "type": "object",
  "properties": {
    "id": { "type": "integer", "minimum": 1 },
    "name": { "type": "string", "minLength": 1, "maxLength": 100 },
    "email": { "type": "string", "format": "email" },
    "age": { "type": "integer", "minimum": 0, "maximum": 150 }
  },
  "required": ["id", "name", "email"]
}

使用我们的 JSON 格式化工具 在与团队共享前美化你的 Schema 以提高可读性。

类型约束

JSON Schema 支持六种基本类型:

类型描述示例
string文本数据"hello"
number任何数值3.14
integer仅整数42
boolean真或假true
array有序列表[1, 2, 3]
object键值对{"key": "value"}
null空值null

字符串约束

{
  "type": "string",
  "minLength": 1,
  "maxLength": 255,
  "pattern": "^[A-Za-z0-9]+$",
  "format": "email"
}

内置格式包括:emailuridatedate-timeipv4ipv6uuidhostname

数字约束

{
  "type": "number",
  "minimum": 0,
  "maximum": 100,
  "exclusiveMinimum": 0,
  "multipleOf": 0.01
}

数组验证

数组可以验证其元素、长度和唯一性:

{
  "type": "array",
  "items": { "type": "string", "format": "email" },
  "minItems": 1,
  "maxItems": 10,
  "uniqueItems": true
}

元组验证(固定长度数组,每个位置有特定类型):

{
  "type": "array",
  "prefixItems": [
    { "type": "number" },
    { "type": "string" },
    { "type": "boolean" }
  ],
  "items": false
}

对象验证

对象支持属性验证、必填字段和额外属性控制:

{
  "type": "object",
  "properties": {
    "name": { "type": "string" },
    "role": { "enum": ["admin", "editor", "viewer"] }
  },
  "required": ["name", "role"],
  "additionalProperties": false
}

additionalProperties 设为 false 是严格模式,拒绝 Schema 中未定义的任何属性。这对 API 特别有用,可以捕获字段名中的拼写错误。

组合关键词

JSON Schema 支持使用逻辑运算符组合 Schema:

allOf(AND)

数据必须对所有子 Schema 有效:

{
  "allOf": [
    { "$ref": "#/$defs/baseUser" },
    { "properties": { "role": { "const": "admin" } } }
  ]
}

oneOf(XOR)

数据必须对恰好一个子 Schema 有效:

{
  "oneOf": [
    { "properties": { "type": { "const": "email" }, "email": { "type": "string" } } },
    { "properties": { "type": { "const": "phone" }, "phone": { "type": "string" } } }
  ]
}

anyOf(OR)

数据必须对至少一个子 Schema 有效。

条件验证

if/then/else 关键词支持条件验证:

{
  "type": "object",
  "properties": {
    "country": { "type": "string" },
    "postalCode": { "type": "string" }
  },
  "if": {
    "properties": { "country": { "const": "US" } }
  },
  "then": {
    "properties": { "postalCode": { "pattern": "^[0-9]{5}(-[0-9]{4})?$" } }
  },
  "else": {
    "properties": { "postalCode": { "pattern": "^[A-Z0-9 -]+$" } }
  }
}

引用和复用

使用 $ref 引用可复用的定义:

{
  "$defs": {
    "address": {
      "type": "object",
      "properties": {
        "street": { "type": "string" },
        "city": { "type": "string" },
        "country": { "type": "string" }
      },
      "required": ["street", "city", "country"]
    }
  },
  "type": "object",
  "properties": {
    "billingAddress": { "$ref": "#/$defs/address" },
    "shippingAddress": { "$ref": "#/$defs/address" }
  }
}

实际验证

JavaScript (Ajv)

const Ajv = require('ajv');
const ajv = new Ajv();

const validate = ajv.compile(schema);
const valid = validate(data);
if (!valid) console.log(validate.errors);

Python (jsonschema)

from jsonschema import validate, ValidationError

try:
    validate(instance=data, schema=schema)
except ValidationError as e:
    print(f"Validation error: {e.message}")

无需搭建开发环境即可快速验证,将你的 JSON 和 Schema 粘贴到我们的 JSON 验证器

实际示例:API 响应 Schema

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "status": { "enum": ["success", "error"] },
    "data": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "id": { "type": "integer" },
          "name": { "type": "string" },
          "createdAt": { "type": "string", "format": "date-time" }
        },
        "required": ["id", "name"]
      }
    },
    "pagination": {
      "type": "object",
      "properties": {
        "page": { "type": "integer", "minimum": 1 },
        "perPage": { "type": "integer", "minimum": 1, "maximum": 100 },
        "total": { "type": "integer", "minimum": 0 }
      }
    }
  },
  "required": ["status", "data"]
}

常见问题

JSON Schema draft-07 和 2020-12 有什么区别?

Draft 2020-12 引入了若干改进:prefixItems 替代了 items 的元组形式,$dynamicRef 实现了更灵活的引用,词汇表支持允许自定义扩展。新项目使用 2020-12。为了与旧工具兼容,draft-07 仍被广泛支持。

JSON Schema 可以验证字符串字段中的嵌套 JSON 吗?

不能直接验证。JSON Schema 验证已解析的 JSON 结构。如果一个字段包含 JSON 字符串,你需要先解析它再单独验证。一些验证器提供自定义格式验证器可以处理这种情况,但这不是标准的一部分。

相关资源

Published on 2025-07-09
JSON Schema Validation: The Definitive Guide | alltools.one