前言
我们在实际开发中,潜移默化的已经使用过了 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_address 和 shipping_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"
}
}
}