Json Schema

505 阅读2分钟

前言

我们在实际开发中,潜移默化的已经使用过了 json scheme 给我们提供的便利。像我们在前端项目中 package.json 是最常见的文件之一,有没有想过,在我们维护 package.json 属性或属性值的时候,vscode提供的智能提示和属性值校验是如何实现的?下面带着这个疑问,进入今天的文章。

json schema 是什么

json schema 是一种基于 JSON 格式,用于描述 JSON 数据的结构和验证数据类型。简单来说,在vscode可以为我们在编辑 .json 文件时提供语法提示和值校验;也可以,通过提供的方法对 js 对象 进行数据验证。

使用

例如:现在我们需要创建用于填写个人信息的 json 文件,需要对 姓名性别年龄 进行校验,单个文件内存储的可能是 对象,也可能是 数组

1. 创建 schema 文件

{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "type": ["object", "array"],
  "items": {
    "$ref": "#"
  },
  "additionalProperties": false,
  "properties": {
    "name": {
      "type": "string",
      "description": "姓名",
      "minLength": 1
    },
    "gender": {
      "type": "string",
      "description": "性别",
      "enum": ["男", "女"]
    },
    "age": {
      "type": "number",
      "description": "年龄",
      "minimum": 0
    }
  },
  "required": ["name", "gender", "age"]
}

2、引用

对象方式引用

{
    "$schema": "./schema.json",
    "name": "zhangsan",
    "gender": "男",
    "age": 23
}

数组方式引用。这个时候发现 $schema 的引用没地方填写,但发现 package.json 也并没有通过 $schema 进行引用。

通过查阅资料,发现vscode里有相关的配置项,我们在当前项目中创建 .vscode 文件夹并添加 settings.json 文件,配置如下

{
  "json.schemas": [
    {
      "fileMatch": [
        "**/xxx/*.json"
      ],
      "url": "/schema.json"
    }
  ]
}

url 字段指定 json schema 配置文件的路径,fileMatch 字段指定生效的文件。完成配置后,我们发现在 fileMatch 生效的文件下,就会按照 json schema 规则进行提示和校验了

说明

基础字段

  • "$schema" 指定遵循哪个草案
  • "$id" 一个唯一标识符,通常是一个 URI,用于标识这个 schema
  • title 标题
  • description 描述
  • type 类型。"object"、"array"、"string"、"number"、"integer"、"boolean"、"null"

对象字段

  • properties 定义对象的属性,每个属性都可以包含其自身的schema
    • description
    • type
  • required 一个属性名数组,定义哪些属性是必须有值的
  • additionalProperties 指定对象是否允许包含 schema 中未定义的属性。可以是布尔值或 schema

数组字段

items

定义数组中每个元素的 schema。如果每个元素的 schema 相同,可以直接指定一个 schema;如果元素的 schema 不同,可以指定一个 schema 列表。

{
    "$schema": "http://json-schema.org/draft-07/schema#",
    "type": ["array", "object"],
    "items": {
        "$ref": "#"
    }
}

items 中 $refs 设置为 #,表示引用自身

minItems: 定义数组的最小长度

uniqueItems: 一个布尔值,表示数组中的元素是否必须唯一

字符串相关字段

  • minLength 定义字符串最小长度
  • maxLength 定义字符串最大长度
  • pattern 定义字符串必须匹配的正则表达式模式

数字相关字段

  • minimum 定义数值的最小值
  • maximum 定义数值的最大值
  • exclusiveMinimum 定义严格的最小值(不包括这个值)
  • exclusiveMaximum 定义严格的最大值(不包括这个值)

组合模式字段

  • allOf 所有指定的 schema 都必须匹配
  • anyOf 任一指定的 schema 匹配即可
  • oneOf 仅一个指定的 schema 必须匹配
  • not 指定的 schema 不得匹配

条件字段

  • if
  • then
  • else

注释字段

  • examples 提供数据的示例
  • default 指定属性的默认值

其他字段

definitions

{
    "$schema": "http://json-schema.org/draft-07/shcema#",
    "definitions": {
        "address": {
            "type": "object",
            "properties": {
                "street_address": {
                    "type": "string"
                },
                "city": {
                    "type": "string"
                },
                "state": {
                    "type": "string"
                }
            },
            "required": ["street_adress", "city", "state"]
        }
    },
    "type": "object",
    "properties": {
        "billing_address": {
            "$ref": "#/defintions/address"
        },
        "shipping_address": {
            "$ref": "#/defintions/address"
        }
    }
}

在上述示例中,definitions 字段定义了一个 address 子schema。然后,billing_addressshipping_address 属性通过 $ref 字段引用这个 子 schema,从而避免重复定义 address 结构

定义子 schema, 在 definitions 字段中可以定义任意多个 子 schema,每个 子 schema 都可以有自己的结构和约束条件

{
    "definitions": {
        "positiveInteger": {
            "type": "integer",
            "minimum": 0,
            "exclusiveMinimum": true
        },
        "nonEmptyString": {
            "type": "string",
            "minLength": 1
        }
    }
}

引用子schema, 使用$ref 字段引用在 definitions 中定义的 子 schema。引用格式为 "#/definitions/子schema名"

{
    "type": "object",
    "properties": {
        "age": {
            "$ref": "#/definitions/positiveInteger"
        },
        "name": {
            "$ref": "#/definitions/nonEmptyString"
        }
    }
}