php json schema,JSON Schema Validation介绍

工作中经常会开发一些接口公布出去,接口以HTTPHandler方式挂载在ASP.NET上,是以*.filetype的后缀形式路由到具体的处理类中。接口参数以JSON格式通过post方法写在Request body中,宿主的ERP系统并没有提供对应的参数校验框架,因此无法像其他基于其他API框架的形式,对输入参数进行统一的校验。

本文针对这种情况,将介绍下JSON.NET自带的JSON Schema校验方式。

之前在API实现中,对于多个参数的校验,往往是一并验证其合法性,否则只能依次校验单个参数,这样代码会显得很冗长。

如,若要对每个参数都进行校验,其方法实现大体如下:void DoSomething(object parma1, object parma2, object parma3)

{

if(param1 is invalid) throw exeception(param1 is invalid)

if(param2 is invalid) throw exeception(param2 is invalid)

if(param3 is invalid) throw exeception(param3 is invalid)

//do something

}

上述参数的合法性校验的代码块,不利于代码的阅读,也会使得这些非业务的处理方法充斥在整个方法中,干扰了关键的业务。因此,对于一些关键参数却无对应错误业务场景的参数,我都放在一起来校验:

如:void DoSomething(object parma1, object parma2, object parma3)

{

if((param1 is invalid) or (parma2 is invalid) or (parma3 is invalid)

throw exeception(params has invalid)

//do something

}

这样从代码长度来看是简洁了,可读性高了,可却给API使用者带来了困惑,对于多个参数来说,这里无法返回具体是哪个参数非法,给使用者带来了差错负担。因为平时很多API都是公布给部门多个同事使用,虽然API文档中有参数示例,但因为对于系统不是很熟悉,总免不了要来询问,每次都要一一解答,查看参数,个人觉得不胜其烦。于是想看看如何实现更友好、简洁的统一校验参数。

JSON Validation

由于API方法的参数都来自于HTTP请求中的Body,body是JSON格式的字符串,因此自然想到从JSON入手。项目中用的是JSON.NET,通过其官网文档发现有JSON validation这个功能,于是花了一上午的时间大致看了下各个文档,有了一定的了解。下面通过一个简单的例子来介绍下JSON Validation的使用方式,假设我们通过JSON串来表示产品目录,每个产品包含以下几个属性:* productId:产品标识

* productName:产品名称

* price: 售价

* tags: 可选的标签

那么我们可能会得到以下的JSON串:{

"productId": 1,

"productName": "A green door",

"price": 12.50,

"tags":["home", "green"]

}

JSON Scheme

JSON.NET Schema是用来校验任何JSON的合法性,它可以对已存在的JSON串进行校验或者用来校验你读取或写入的JSON格式。具体的介绍参考 JSON Schema。

下面来看一下Schema的结构:{

"$schema": "http://json-schema.org/draft-07/schema#",

"$id": "http://example.com/product.schema.json",

"title": "Product",

"description": "A product in the catalog",

"type": "object"

}

各属性含义如下:* Schema Keyword: $shema和$id

* Scheme Annotations: title和description

* Validation Keyword: type

实际上Scheme Keyword和Schema Annotation在一般情况下都是可以忽略的,我们要关注的是Validation Keyword和下面要介绍的properties.

根据产品的特性,productId可以是一个唯一的数字值,且不能为空。

因此我们在前面的JSON Schema中添加一下特性:* properties: 这个是validation keyword的关键字,用于表述对具体元素的校验规则;

* productId:假设为整形,且不能为空;

* required:validation关键字,是一个数组,表示数组内的元素不能缺省。

加入之后的JSON Schema如下:{

"$schema": "http://json-schema.org/draft-07/schema#",

"$id": "http://example.com/product.schema.json",

"title":"Product",

"description":"A product catalog",

"type":"object",

"properties": {

"productId":{

"description":"The unique identifier form a product",

"type":"integer"

}

},

"required":["productId"]

}

对于productName字段,type应该为string, 且不能为空,因此也是应该在required数组里面。

下面来谈谈price, type当然不能是integer了,因为正常都是包含小数的,所以应该是数值型number即可。而天下没有免费的午餐,所以我们可以添加规定值必须大于0.

将上述两个字段添加后的Schema如下:{

"$schema": "http://json-schema.org/draft-07/schema#",

"$id": "http://example.com/product.schema.json",

"title": "Product",

"description": "A product from Acme's catalog",

"type": "object",

"properties": {

"productId": {

"description": "The unique identifier for a product",

"type": "integer"

},

"productName": {

"description": "Name of the product",

"type": "string"

},

"price": {

"description": "The price of the product",

"type": "number",

"exclusiveMinimum": 0

}

},

"required": [ "productId", "productName", "price" ]

}

这里的exclusiveMinium:0,表示输入的值必须大于0. 如果对于exclusiveMinium关键词属性不清晰,可以参见JSON Schema的说明文档: json-schema-validation。

接下来再看看tags属性,一个商品可以有很多标签,但标签之间应该不能重复。所以tags的校验应该是一个数组,且数组元素之间是唯一的。

只对tags属性来看:"tags": {

"description": "Tags for the product",

"type": "array",

"items": {

"type": "string"

},

"minItems": 1,

"uniqueItems": true

}

可以看到这里type为array表示一个数组,items是对数组里面的每个元素而言,minItems和uniqueItems则其义自见了。

嵌套的Schema

有时候我们的JSON串可能是嵌套的,如产品有尺寸的属性,用长、宽、高来表示。这时尺寸是product的元素,而尺寸本身也是一个对象,与product拥有相同的JSON validation结构。在我们的Validation中,只需要将dimensions的type指定为object,即可以用properties来校验其子元素。

将上述部分全部整合后的JSON Schema validation如下:{

"$schema": "http://json-schema.org/draft-07/schema#",

"$id": "http://example.com/product.schema.json",

"title": "Product",

"description": "A product from Acme's catalog",

"type": "object",

"properties": {

"productId": {

"description": "The unique identifier for a product",

"type": "integer"

},

"productName": {

"description": "Name of the product",

"type": "string"

},

"price": {

"description": "The price of the product",

"type": "number",

"exclusiveMinimum": 0

},

"tags": {

"description": "Tags for the product",

"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" ]

}

},

"required": [ "productId", "productName", "price" ]

}

最后,我们给出一个符合上述validation的JSON串:{

"productId": 1,

"productName": "An ice sculpture",

"price": 12.50,

"tags": [ "cold", "ice" ],

"dimensions": {

"length": 7.0,

"width": 12.0,

"height": 9.5

}

}

JSON.NET提供了在线校验的工具,可以根据你定义的Schema Validation实时反馈输入的JSON串是否合法。对于日常开发时,可以先根据参数将对应的Schema定义好,这样可以节省不少调试的时间。Online Validation Tool.

Reference:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值