zoukankan      html  css  js  c++  java
  • web接口参数校验神器-json schema 快速入门

    Json Schema 快速入门

    JSON 模式是一种基于 JSON 格式定义 JSON 数据结构的规范。它被写在 IETF 草案下并于 2011 年到期。JSON 模式:

    • 描述现有数据格式。
    • 干净的人类和机器可读的文档。
    • 完整的结构验证,有利于自动化测试。
    • 完整的结构验证,可用于验证客户端提交的数据。

    Json schema 格式

    Json schema 本身遵循Json规范,本身就是一个Json字符串,先来看一个例子

    {
        "$schema": "http://json-schema.org/draft-04/schema#",
        "title": "Product",
        "description": "A product from Acme's catalog",
        "type": "object",
        "properties": {
            "id": {
                "description": "The unique identifier for a product",
                "type": "integer"
            },
            "name": {
                "description": "Name of the product",
                "type": "string"
            },
            "price": {
                "type": "number",
                "minimum": 0,
                "exclusiveMinimum": true
            }
        },
        "required": ["id", "name", "price"]
    }

    我们来看一下json schema 最外层包含以下几个字段

    $schema描述示例
    $schema $schema 关键字状态,表示这个模式与 v4 规范草案书写一致。  
    title 标题,用来描述结构  
    description 描述  
    type 类型 .
    properties 定义属性  
    required 必需属性

    上面只是一个简单的例子,从上面可以看出Json schema 本身是一个JSON字符串,由通过key-value的形式进行标示。
    type 和 properties 用来定义json 属性的类型。required 是对Object字段的必段性进行约束。事实上,json Schema定义了json所支持的类型,每种类型都有0-N种约束方式。下一节我们来,细致介绍一下。


    Json schema 类型

    Object

    {
        "$schema": "http://json-schema.org/draft-04/schema#",
        "title": "Product",
        "description": "A product from Acme's catalog",
        "type": "object",
        "properties": {
            "id": {
                "description": "The unique identifier for a product",
                "type": "integer"
            },
            "name": {
                "description": "Name of the product",
                "type": "string"
            },
            "price": {
                "type": "number",
                "minimum": 0,
                "exclusiveMinimum": true
            }
        },
        "required": ["id", "name", "price"]
    }

    object类型有三个关键字:type(限定类型),properties(定义object的各个字段),required(限定必需字段),如下:
    | 关键字 | 描述 | 示例 |
    |:------------- |:---------------| ----- |
    | type |类型|. |
    | properties |定义属性||
    | required|必需属性||
    | maxProperties |最大属性个数||
    | minProperties |最小属性个数||
    | additionalProperties |true or false or object|参考|
    properties 定义每个属性的名字和类型,方式如上例。

    array

    {
        "$schema": "http://json-schema.org/draft-04/schema#",
        "title": "Product",
        "description": "A product from Acme's catalog",
        "type": "array",
        "items": {
            "type": "string"
         },
         "minItems": 1,
         "uniqueItems": true
        }

    array有三个单独的属性:items,minItems,uniqueItems:

    关键字描述示例
    items array 每个元素的类型 .
    minItems 约束属性,数组最小的元素个数  
    maxItems 约束属性,数组最大的元素个数  
    uniqueItems 约束属性,每个元素都不相同  
    additionalProperties 约束items的类型,不建议使用 示例
    Dependencies 属性依赖 用法
    patternProperties   用法

    string

    {
       "$schema": "http://json-schema.org/draft-04/schema#",
        "title": "Product",
        "description": "A product from Acme's catalog",
        "type": "object",
        "properties": {
            "ip": {
                "mail": "string",
                "pattern":"w+([-+.]w+)*@w+([-.]w+)*.w+([-.]w+)*"
            },
            "host": {
                "type": "phoneNumber",
                "pattern":"((d{3,4})|d{3,4}-)?d{7,8}(-d{3})*"
            },
        },
        "required": ["ip", "host"]
    }
    

      

    关键字描述示例
    maxLength 定义字符串的最大长度,>=0 .
    minLength 定义字符串的最小长度,>=0  
    pattern 用正则表达式约束字符串

    integer

    {
        "$schema": "http://json-schema.org/draft-04/schema#",
        "title": "Product",
        "description": "A product from Acme's catalog",
        "type": "object",
        "properties": {
            "name": {
                "description": "Name of the product",
                "type": "string"
            },
            "price": {
                "type": "integer",
                "minimum": 0,
                "exclusiveMinimum": true
            }
        },
        "required": ["id", "name", "price"]
    }

    number

    {
        "$schema": "http://json-schema.org/draft-04/schema#",
        "title": "Product",
        "description": "A product from Acme's catalog",
        "type": "object",
        "properties": {
            "name": {
                "description": "Name of the product",
                "type": "string"
            },
            "price": {
                "type": "number",
                "minimum": 0,
                "exclusiveMinimum": true
            }
        },
        "required": ["id", "name", "price"]
    }
    
    | 关键字      | 描述  |    示例   |
    |:------------- |:---------------| ----- |
    | minimum |最小值|. |
    | exclusiveMinimum |如果存在 "exclusiveMinimum" 并且具有布尔值 true,如果它严格意义上大于 "minimum" 的值则实例有效。||
    | maximum |约束属性,最大值||
    | exclusiveMaximum |如果存在 "exclusiveMinimum" 并且具有布尔值 true,如果它严格意义上小于 "maximum" 的值则实例有效。||
    | multipleOf |是某数的倍数,必须大于0的整数||

    number 关键字可以描述任意长度,任意小数点的数字。number类型的约束有以下几个:

    关键字描述示例
    minimum 最小值 .
    exclusiveMinimum 如果存在 "exclusiveMinimum" 并且具有布尔值 true,如果它严格意义上大于 "minimum" 的值则实例有效。  
    maximum 约束属性,最大值  
    exclusiveMaximum 如果存在 "exclusiveMinimum" 并且具有布尔值 true,如果它严格意义上小于 "maximum" 的值则实例有效。

    boolean

    {
    "type": "object",
    "properties": {
    "number": { "type": "boolean" },
    "street_name": { "type": "string" },
    "street_type": { "type": "string",
    "enum": ["Street", "Avenue", "Boulevard"]
    }
    }
    }

    true or false

    enum

    {
      "type": "object",
      "properties": {
        "number":      { "type": "number" },
        "street_name": { "type": "string" },
        "street_type": { "type": "string",
                         "enum": ["Street", "Avenue", "Boulevard"]
                       }
      }
    }

    也可以这么做

    {
      "type": "object",
      "properties": {
        "number":      { "type": "number" },
        "street_name": { "type": "string" },
        "street_type": ["Street", "Avenue", "Boulevard"]                   
      }
    }

    null

    进阶

    了解了上面的各个类型的定义及约定条件,就可以满足大部分情况了。但为了写出更好的json schema,我们再学习几个关键字

    $ref

    $ref 用来引用其它schema,
    示例如下:

    {
        "$schema": "http://json-schema.org/draft-04/schema#",
        "title": "Product set",
        "type": "array",
        "items": {
            "title": "Product",
            "type": "object",
            "properties": {
                "id": {
                    "description": "The unique identifier for a product",
                    "type": "number"
                },
                "name": {
                    "type": "string"
                },
                "price": {
                    "type": "number",
                    "minimum": 0,
                    "exclusiveMinimum": true
                },
                "tags": {
                    "type": "array",
                    "items": {
                        "type": "string"
                    },
                    "minItems": 1,
                    "uniqueItems": true
                },
                "dimensions": {
                    "type": "object",
                    "properties": {
                        "length": {"type": "number"},
                        "width": {"type": "number"},
                        "height": {"type": "number"}
                    },
                    "required": ["length", "width", "height"]
                },
                "warehouseLocation": {
                    "description": "Coordinates of the warehouse with the product",
                    "$ref": "http://json-schema.org/geo"
                }
            },
            "required": ["id", "name", "price"]
        }
    }

    definitions

    当一个schema写的很大的时候,可能需要创建内部结构体,再使用$ref进行引用,示列如下:

    {
        "type": "array",
        "items": { "$ref": "#/definitions/positiveInteger" },
        "definitions": {
            "positiveInteger": {
                "type": "integer",
                "minimum": 0,
                "exclusiveMinimum": true
            }
        }
    }

    allOf

    意思是展示全部属性,建议用requires替代

    不建议使用,示例如下

    {
      "definitions": {
        "address": {
          "type": "object",
          "properties": {
            "street_address": { "type": "string" },
            "city":           { "type": "string" },
            "state":          { "type": "string" }
          },
          "required": ["street_address", "city", "state"]
        }
      },
    
      "allOf": [
        { "$ref": "#/definitions/address" },
        { "properties": {
            "type": { "enum": [ "residential", "business" ] }
          }
        }
      ]
    }

    anyOf

    意思是展示任意属性,建议用requires替代和minProperties替代,示例如下:

    {
      "anyOf": [
        { "type": "string" },
        { "type": "number" }
      ]
    }

    oneOf

    其中之一

    {
      "oneOf": [
        { "type": "number", "multipleOf": 5 },
        { "type": "number", "multipleOf": 3 }
      ]
    }

    not

    非 * 类型
    示例

    { "not": { "type": "string" } }
     
  • 相关阅读:
    linux的vim按了ctrl+s之后假死的解决办法
    linux下的终端模拟器urxvt的配置
    vim下正则表达式的非贪婪匹配
    linux中的一个看图的软件
    解决windows的控制台显示utf8乱码的问题
    [PHP][位转换积累]之异或运算的简单加密应用
    [PHP][REDIS]phpredis 'RedisException' with message 'read error on connection'
    [PHP][位转换积累]之与运算截取二进制流的值
    [PHP][位转换积累]之pack和unpack
    [正则表达式]PCRE反向分组引用
  • 原文地址:https://www.cnblogs.com/lianhaifeng/p/11886451.html
Copyright © 2011-2022 走看看