3. JSON Schema 入门:定义 Redis Value 的契约

在 Redis 契约校验体系中,JSON Schema 是描述 Value 结构最核心的语言。它不关心数据如何存储,只关心数据“应该长什么样”。本章从零开始,掌握 JSON Schema 的基本语法、关键字,并学会为 Redis Value 编写精确的 Schema 定义。

3.1 什么是 JSON Schema

JSON Schema 是一种基于 JSON 格式的声明式语言,用于描述 JSON 数据的结构、类型和约束。你可以把它理解为“数据的身份证”——它规定了某个 JSON 对象必须包含哪些字段、字段的类型是什么、取值范围是多少。

核心思想:JSON Schema 本身也是一个 JSON 对象,通过特定的关键字(如 type、properties、required)来描述另一个 JSON 数据的规则。

3.2 基本语法与结构

一个最简单的 JSON Schema 通常包含以下结构:

{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "$id": "https://example.com/user-schema.json",
  "title": "User Profile",
  "description": "用户基本信息 Schema",
  "type": "object",
  "properties": {
    "username": { "type": "string" },
    "age": { "type": "integer" }
  },
  "required": ["username"]
}
关键字 作用 是否必须
$schema 声明使用的 Schema 规范版本 推荐
$id Schema 的唯一标识 URI 可选
title Schema 的简短标题 可选
description Schema 的详细说明 可选
type 定义数据的类型(string、number、object、array、boolean、null) 必须
properties 定义对象类型下的各个字段 当 type 为 object 时使用
required 声明哪些字段是必须存在的 可选

3.3 核心关键字详解

3.3.1 类型约束

type 是最基础的关键字,支持以下 7 种类型:

  • string — 字符串
  • number — 数字(整数或浮点数)
  • integer — 整数
  • boolean — 布尔值
  • object — 对象
  • array — 数组
  • null — 空值
注意:Redis 中存储的 JSON 值通常为 object 或 array 类型。如果 Value 是简单字符串或数字,Schema 只需定义 type 即可。

3.3.2 字符串约束

关键字 说明 示例
minLength 最小长度 "minLength": 1
maxLength 最大长度 "maxLength": 100
pattern 正则表达式匹配 "pattern": "^[a-zA-Z0-9]+$"
format 预定义格式(email、date-time、uri 等) "format": "email"
enum 枚举值列表 "enum": ["admin", "user", "guest"]

3.3.3 数字约束

关键字 说明 示例
minimum 最小值(包含) "minimum": 0
maximum 最大值(包含) "maximum": 150
exclusiveMinimum 最小值(不包含) "exclusiveMinimum": 0
exclusiveMaximum 最大值(不包含) "exclusiveMaximum": 100
multipleOf 必须是某数的倍数 "multipleOf": 5

3.3.4 数组约束

关键字 说明 示例
items 定义数组元素的 Schema "items": { "type": "string" }
minItems 最小元素个数 "minItems": 1
maxItems 最大元素个数 "maxItems": 10
uniqueItems 元素是否必须唯一 "uniqueItems": true

3.3.5 对象约束

关键字 说明 示例
properties 定义每个字段的 Schema "properties": { "name": { "type": "string" } }
required 必须存在的字段列表 "required": ["name", "email"]
additionalProperties 是否允许未定义的字段 "additionalProperties": false
minProperties 对象最少字段数 "minProperties": 1
maxProperties 对象最多字段数 "maxProperties": 20

3.4 如何定义 Redis Value 的 Schema

在 Redis 中,Value 可以是任意 JSON 结构。定义 Schema 时,需要先确定 Value 的顶层类型,然后逐层描述内部字段。

步骤流程:

  1. 确定顶层类型 — 通常是 object 或 array
  2. 列出所有字段 — 使用 properties 定义每个字段
  3. 标记必填字段 — 使用 required 列出必须存在的字段名
  4. 约束字段类型 — 为每个字段设置 type 和附加约束
  5. 控制额外字段 — 使用 additionalProperties 决定是否允许未声明的字段
实战案例:假设 Redis 中存储了一个用户会话对象,Value 结构如下:
{
  "userId": "u_1001",
  "role": "admin",
  "loginCount": 42,
  "tags": ["vip", "2024"],
  "profile": {
    "nickname": "Alice",
    "avatar": "https://example.com/avatar.png"
  }
}
对应的 Schema 定义:
{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "title": "User Session",
  "type": "object",
  "properties": {
    "userId": {
      "type": "string",
      "pattern": "^u_\\d+$",
      "description": "用户ID,以 u_ 开头"
    },
    "role": {
      "type": "string",
      "enum": ["admin", "user", "guest"]
    },
    "loginCount": {
      "type": "integer",
      "minimum": 0
    },
    "tags": {
      "type": "array",
      "items": { "type": "string" },
      "minItems": 1,
      "uniqueItems": true
    },
    "profile": {
      "type": "object",
      "properties": {
        "nickname": { "type": "string", "minLength": 1 },
        "avatar": { "type": "string", "format": "uri" }
      },
      "required": ["nickname"],
      "additionalProperties": false
    }
  },
  "required": ["userId", "role", "loginCount"],
  "additionalProperties": false
}

3.5 JSON Schema 校验流程

JSON Schema 校验流程 JSON Schema 校验流程 原始 JSON 数据 加载 JSON Schema 逐字段校验类型与约束 ✅ 校验通过 ❌ 校验失败 校验失败时返回具体错误路径与原因,便于定位问题

3.6 常见避坑指南

⚠️ 常见错误 1:忘记设置 additionalProperties
默认情况下,additionalProperties 为 true,意味着对象可以包含任何未在 properties 中声明的字段。如果希望严格约束,必须显式设置为 false。
⚠️ 常见错误 2:required 与 properties 不匹配
required 中列出的字段名必须在 properties 中有定义,否则校验器会报错。
💡 最佳实践:为每个 Redis Key 的 Value 单独编写 Schema,并存储在独立的 .json 文件中。在应用启动时加载到内存,避免每次校验都读取磁盘。

3.7 本章小结

  • JSON Schema 是描述 JSON 数据结构的声明式语言,核心关键字包括 type、properties、required、additionalProperties 等。
  • 字符串、数字、数组、对象各有专属约束关键字,如 pattern、minimum、minItems、uniqueItems。
  • 定义 Redis Value 的 Schema 时,先确定顶层类型,再逐层描述字段,最后通过 required 和 additionalProperties 控制严格程度。
  • 校验流程分为加载 Schema、逐字段校验、输出通过/失败结果三个步骤。