Json-schema

Json-schema

前端与服务器端的交互过程,大部分时候是使用的json格式

对于json还是比较了解,可是json-schema是什么?

json–JavaScript Object Notation JavaScript对象表示法

json-schema是一个用于验证json数据格式的工具,它本身也是使用json语言编写的

Json Schema定义了一套词汇和规则,这套词汇和规则用来定义Json元数据,且元数据也是通过Json数据形式表达的。Json元数据定义了Json数据需要满足的规范,规范包括成员、结构、类型、约束等

Json-schema示例

json-schema举例:

{
    "$schema": "https://json-schema.org/draft/2019-09/schema",
    "$id": "https://json-schema.org/draft/2019-09/schema",
    "$vocabulary": {
        "https://json-schema.org/draft/2019-09/vocab/core": true,
        "https://json-schema.org/draft/2019-09/vocab/applicator": true,
        "https://json-schema.org/draft/2019-09/vocab/validation": true,
        "https://json-schema.org/draft/2019-09/vocab/meta-data": true,
        "https://json-schema.org/draft/2019-09/vocab/format": false,
        "https://json-schema.org/draft/2019-09/vocab/content": true
    },
    "$recursiveAnchor": true,

    "title": "Core and Validation specifications meta-schema",
    "allOf": [
        {"$ref": "meta/core"},
        {"$ref": "meta/applicator"},
        {"$ref": "meta/validation"},
        {"$ref": "meta/meta-data"},
        {"$ref": "meta/format"},
        {"$ref": "meta/content"}
    ],
    "type": ["object", "boolean"],
    "properties": {
        "definitions": {
            "$comment": "While no longer an official keyword as it is replaced by $defs, this keyword is retained in the meta-schema to prevent incompatible extensions as it remains in common use.",
            "type": "object",
            "additionalProperties": { "$recursiveRef": "#" },
            "default": {}
        },
        "dependencies": {
            "$comment": "\"dependencies\" is no longer a keyword, but schema authors should avoid redefining it to facilitate a smooth transition to \"dependentSchemas\" and \"dependentRequired\"",
            "type": "object",
            "additionalProperties": {
                "anyOf": [
                    { "$recursiveRef": "#" },
                    { "$ref": "meta/validation#/$defs/stringArray" }
                ]
            }
        }
    }
}

在上述文件中,有些是json-schema规定的特殊字符,也即具有特殊涵义的字符,我们称之为关键字或保留字,有些是根据我们的需要随便编写的相关内容,

关键字说明

关键字描述示例
$schema主要用于声明当前文件使用的json模式,遵守的是那个版本json模式的规范上述示例是遵守2019-09发布的那个版本
$id用于作为模式的唯一标识符,一般指向一个自主域名。方便后续引用
$ref引用一个定义的模式
$vocabulary
$recursiveAnchor
$recursiveRef
$comment仅仅是为模式添加注释用(New in draft 7)
type类型:string\number\boolean\array\object\null
properties属性,用于定义对象中的属性
required用于定义对象中必须含有的属性
enum表示json数据的取值只能是list中的某个数组
title标题,用它给我们的模式提供了标题
description关于模式的描述。
default默认值
example一个符合约束条件的模式示例

title,description,default,example只作为描述作用,不影响对数据的校验。

对复杂结构的支持包括定义和引用。当多个元素使用相同的校验模式时,可以将相同的结构校验定义成一个“类型”,需要使用该“类型”时,可以通过其路径或id来引用

definations-用于定义通用类型模式

定义一个类型,并不需要特殊的关键字。通常的习惯是在root节点的 definations 下面,定义需要多次引用的schema。definations是一个json对象,key是想要定义的“类型”的名称,value是一个json schema

{
    "definitions": {
        "address": {//定义的一个通用的模式
            "type": "object",
            "properties": {
                "street_address": { "type": "string" },
                "city":           { "type": "string" },
                "state":          { "type": "string" }
            },
            "required": ["street_address", "city", "state"]
        }
    },
    "type": "object",
    "properties": {
        "billing_address": { "$ref": "#/definitions/address" },
        "shipping_address": { "$ref": "#/definitions/address" }
    }
}

$ref

上例中定义了一个address的schema,并且在两个地方通过路径的方式引用了它,#/definitions/address表示从根节点开始的路径

$id

{
    "definitions": {
        "address": {//定义的一个通用的模式
            "type": "object",
            "$id" : "address",
            "properties": {
                "street_address": { "type": "string" },
                "city":           { "type": "string" },
                "state":          { "type": "string" }
            },
            "required": ["street_address", "city", "state"]
        }
    },
    "type": "object",
    "properties": {
        "billing_address": { "$ref": "#address"},
        "shipping_address": { "$ref":"#address"}
    }
}

可以在上面的定义中加入id属性,这样可以通过id属性的值对该schema进行引用,而不需要完整的路径。

type

定义模式属性的类型,可以是单选也可以提供多个类型:

type的可选值包括:string\number\boolean\array\object\null

仅有一个类型可选:{ "type": "string" }

可以有多个类型可选:{ "type": ["number", "string"] }

当type与enum发生冲突的时候,以type约束为先:

{
  "type": "string",
  "enum": ["red", "amber", "green", null]
}

null值与"type": "string"冲突,此时若选值null则检测不通过

约束条件

string 类型的约束条件

关键字描述取值类型
maxLength字符串实例字符的最大长度(非负)≥0
minLength字符串实例字符的最小长度(非负)≥0
pattern限定字符串应符合的表达式条件,符合则有效表达式
formatJson Schema内建的一些规则,对字符串的格式做约束,例如电子邮件、日期、域名等

format包括"date", “time”, “date-time”, “email”, “hostname”,“ipv4”,"uri"等
“json-pointer”,“regex”

number类型的约束条件

number:数字类型
integer:必须是整数

关键字描述取值类型
minimum表示可以接受的最小值。 x ≥ minimum数值型
maximum表示可以接受的最大值。 x ≤ maximum数值型
exclusiveMinimum开区间最小值,排除等于的情况。x > exclusiveMinimum数值型
exclusiveMaximum开区间最大值,排除等于的情况。x < exclusiveMaximum数值型
multipleOf要求数值必须是该指定值的整数倍数值型

array类型的约束条件

关键字描述取值类型
minItems表示数组内最少元素个数数值型
maxItems表示数组内最多元素个数数值型
items要求数组内每个成员都是某种类型{“type”: “number”}或者[{“type”: “number”},{“type”: “string”}]
additionalItems数组是否允许额外成员,配合items使用booloan,或限制条件
uniqueItems约束数组中每项不得重复booloan
contains最少有一个符合条件

示例:

  "type": "array",
  "items": [
    {//0
      "type": "number"
    },
    {//1
      "type": "string"
    },
    {//2
      "type": "string",
      "enum": ["Street", "Avenue", "Boulevard"]
    },
    {//4
      "type": "string",
      "enum": ["NW", "NE", "SW", "SE"]
    }
  ],
  "minItems": 1,
  "maxItems": 5,
  "additionalItems": {
        "type": "string",
        "minLength": 2
   },
  "uniqueItems": true
}
items & additionalItems

items列出了多个约束条件时,对应索引的项如果存在必须符合约束条件

  • additionalItems属性不存在

    • 数组长度小于items,只要存在的项符合约束条件即可,也即数组长度可以小于items
    • 数组长度大于items且额外元素没有约束条件
  • 存在additionalItems属性,数组的长度受限于 additionalItems:

    • 数组长度若小于items,只要存在的项符合约束条件即可,不受 additionalItems影响
    • 如果additionalItems为true,没有额外约束,数组长度可以大于items,因为后面的元素没有对应索引的items约束条件因此无约束

示例:

{
  "type": "array",
  "items": [
    {
      "type": "number"
    },
    {
      "type": "string"
    },
    {
      "type": "string",
      "enum": ["Street", "Avenue", "Boulevard"]
    },
    {
      "type": "string",
      "enum": ["NW", "NE", "SW", "SE"]
    }
  ],
  "additionalItems": true
}
  • 如果additionalItems 有额外的约束,额外的元素必须符合additionalItems 的约束条件
  "type": "array",
  "items": [
    {//0
      "type": "number"
    },
    {//1
      "type": "string"
    }
  ],
  "minItems": 1,
  "maxItems": 5,
  "additionalItems": {
        "type": "string",
        "minLength": 2
   },
  "uniqueItems": true
}
  • 如果additionalItems为 false,数组长度只能<=items的长度
{
  "type": "array",
  "items": [
    {
      "type": "number"
    },
    {
      "type": "string"
    },
    {
      "type": "string",
      "enum": ["Street", "Avenue", "Boulevard"]
    },
    {
      "type": "string",
      "enum": ["NW", "NE", "SW", "SE"]
    }
  ],
  "additionalItems": false
}
contains(New in draft 6)

示例:

{
   "type": "array",
   "contains": {
     "type": "number"
   }
}
e.g :["life", "universe", "everything", 42]//最少有一个符合条件

object类型的约束条件

关键字描述取值类型
required约束对象必须具有的属性字段数组
properties用于定义对象属性和对应值的类型,以及用于 JSON 文件中的最小值和最大值。
propertyNames用于定义对象properties中的属性名称需要满足的约束
patternProperties批量定义对象Schema
dependencies规定某些属性之间的依赖,不能在依赖属性缺席的情况下单独出现,属于数据完整性方面的约束。
additionalProperties规定object类型是否允许出现不在properties中规定的属性可以取true/false,或者直接设置约束规则
minProperties规定最少有几个属性成员
maxProperties规定最多有几个属性成员
const用于设定属性的值
propertyNames(New in draft 6)

示例:

{
  "type": "object",
  "propertyNames": {
    "pattern": "^[A-Za-z_][A-Za-z0-9_]*$"
  }
}
const(New in draft 6)

设定值后不允许属性设置为其他值

{ “const”: “United States of America” }
等价于
{ “enum”: [ “United States of America” ] }

dependencies

属性间的依赖

{
  "type": "object",

  "properties": {
    "name": { "type": "string" },
    "credit_card": { "type": "number" },
    "billing_address": { "type": "string" }
  },

  "required": ["name"],

  "dependencies": {
    "credit_card": ["billing_address"],
    "billing_address": ["credit_card"]
  }
}

单独定义依赖的属性模式

{
  "type": "object",

  "properties": {
    "name": { "type": "string" },
    "credit_card": { "type": "number" }
  },

  "required": ["name"],

  "dependencies": {//credit_card依赖的属性
    "credit_card": {
      "properties": {
        "billing_address": { "type": "string" }
      },
      "required": ["billing_address"]
    }
  }
}

只要credit_card属性存在,billing_address必须存在

additionalProperties

用法类似于additionalItems

additionalProperties不受properties与patternProperties的约束条件限制

{
  "type": "object",
  "properties": {
    "builtin": { "type": "number" }
  },
  "patternProperties": {
    "^S_": { "type": "string" },
    "^I_": { "type": "integer" }
  },
  "additionalProperties": { "type": "string" }
}

逻辑组合的约束条件

关键字描述取值类型
allOf满足所有约束条件,"allOf"的内容是一个数组,数组内的成员都是内嵌的Json Schema
anyOf满足anyOf数组中的任意个Schema
oneOf满足且仅满足oneOf数组中的一个Schema
not它告诉Json不能满足not所对应的Schema

需要注意,使用allOf时,Schema不论在内嵌的Schema里还是外部的Schema里,都不应该使"additionalProperties"为false。否则可能会生成任何数据都无法满足的矛盾Schema。

非json格式数据转化(New in draft 7)

{
  "type": "string",
  "contentEncoding": "base64",
  "contentMediaType": "image/png"
}

if then else

{
  "type": "object",
  "properties": {
    "street_address": {
      "type": "string"
    },
    "country": {
      "enum": ["United States of America", "Canada"]
    }
  },
  "if": {
    "properties": { "country": { "const": "United States of America" } }
  },
  "then": {
    "properties": { "postal_code": { "pattern": "[0-9]{5}(-[0-9]{4})?" } }
  },
  "else": {
    "properties": { "postal_code": { "pattern": "[A-Z][0-9][A-Z] [0-9][A-Z][0-9]" } }
  }
}

以下示例通过 if then实现了 allOf 等同于 oneOf

{
  "type": "object",
  "properties": {
    "street_address": {
      "type": "string"
    },
    "country": {
      "enum": ["United States of America", "Canada", "Netherlands"]
    }
  },
  "allOf": [
    {
      "if": {
        "properties": { "country": { "const": "United States of America" } }
      },
      "then": {
        "properties": { "postal_code": { "pattern": "[0-9]{5}(-[0-9]{4})?" } }
      }
    },
    {
      "if": {
        "properties": { "country": { "const": "Canada" } }
      },
      "then": {
        "properties": { "postal_code": { "pattern": "[A-Z][0-9][A-Z] [0-9][A-Z][0-9]" } }
      }
    },
    {
      "if": {
        "properties": { "country": { "const": "Netherlands" } }
      },
      "then": {
        "properties": { "postal_code": { "pattern": "[0-9]{4} [A-Z]{2}" } }
      }
    }
  ]
}
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

三知之灵

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值