经常用 Python 写代码的同学应该都有一个感触,那就是 Python 对于字典的支持太舒服了,而且基本上可以和 JS 中写 Json 一样舒服。但是,因为 Python 对于 Dict 的支持比较松散,所以,导致了一个问题,假如我有一个函数,参数如果放它一个字典,那调用者会疯掉的,这是一种情况;另外一个常见的场景就是参数校验,无论是 HTTP 还是 RPC 等形式,很多时候我们的参数都是以 JSON 的形式传递的,如何对这结构体进行描述或者验证都是一个比较棘手的问题。

对于 JSON 的这个问题,我关注它也有两年多的时间了,我觉得还没见到一种完美的方式,总是带着一些遗憾,但是不无办法,例如本文就介绍一种还不错的方式,但是,缺点就是语法其实还是比较复杂的,制定 Schema 的时候有阵痛,但是用起来的时候就很方便、很舒服了,这就是我在这篇文章中想介绍的一个 Python Library:JSON Schema。

json schema 简介

关于 json schema 其实无需介绍过多,无非就是一个定义 json 的 schema 的 library,其中肯定包含两部分,第一部分是 Schama 的定义,这个属于文档方面的事情;另一部分就是 Schema 的使用,这是属于开发方面的问题。本文就从这两方面说起,看看 JSON-Schema 是如何处理 json 的 schema 的。

在讲关于这个 python library 之前,顺便聊一些题外话,那就是 json 的 schema 问题,在使用 json-schema 这个 Library 的时候,我被导到一个 json-schema.org 的网站上,然后这里定义了关于 json schema 的相关的规范,最新的版本是 draft-7,从这个版本来看,似乎这还不是正式版本,不过既然有规范,而且我针对我的需求,扫了几圈这个规范,发现是挺完善的,所以,不妨将这个规范用作日常使用。

json schema 定义

json-schema 这个 library 在它的描述中声明目前是完全支持:Draft3 和 Draft4 规范的,所以我这里就以 Draft4 为规范进行 json 的 schema 描述。

先说一下在本文中我将使用的示例背景,在本文中,我将描述一个博客文章的模型,然后这个博客文章会属于一些分类,分类是嵌套在文章中的,这里其实分类和文章是一个多对多的关系,但是因为分类自身比较简单,所以为了简化模型,我将分类嵌入到文章模型中,所以整体模型是这样的:

依照这个模型,我可以先定义一个简单的对应的 json 序列:

接着我们就可以先使用 json-schema 来定义一下我们有哪些 Field,注意,这里我们先不做其他方面的定义进行定义,而只是先看看需要什么 Field,那么一个非常简单的 Schema 就出来了,像这样:

各要素都比较完备了,简单明了的说明了我们的 post 的数据结构,下一步就是定义一下各个字段的类型了。

json schema 类型

在 json schema 中,描述类型都是通过 K-V 的形式进行描述的,并且 Key 肯定是 "type",然后 value 就是对应的类型,这个对应的类型不是随便写的,只能从下面这 6 个中选择:

"null"

"boolean"

"object"

"array"

"number"

"string"

所以我们就可以先填充一下我们的 Schema:

ok,现在看上去这个 Schema 已经有点成效了,但是,对于一些字段我们可能还需要进行更多的限制,例如 status,我们不能让别人随意的发挥,所以自然是需要一些 ENUM 值进行选择,所以也需要制定以下。

json schema 属性

在 json schema 中,字段除了类型,还可以添加一些属性,常用的属性有

enum:列举一些枚举值,表示该字段只能是枚举值中的其中一个,枚举值必须为数值

maxLength/minLength:字符串的长度限制

pattern:字符串必须满足的模式

这里就给我们的 schema 加上一些限制:

似乎更好一些了,然后我们看向了 categories,觉得这个只指定了类型为 array,但是 array 里面的元素应该是什么类型却没有说,所以我们还是需要指定一下的。

json schema 数组

在 json-schema 中,如果要定义数组的元素类型,那么可以通过 items 属性定义,定义的方式就和定义一个对象一致,因此,我们就可以这么搞了:

这样一定义,我们的数组 schema 就完整多了,但是,从这里我们就可以发现,这里的 分类 Model 还比较简单,如果更复杂一些,那么 Post 的 Schema 就比较难看了,有没有一些更好的方式可以简化这个 schema。

json schema 引用

在 json-schema 中,我们经常会有一个 Object 中包含另外一个 Object 的情况,对于这种情况,当然可以在 Object 定义其他 Object,但是,正如前面所说,这样太复杂了,所以,为了更加简单清晰得描述关系,在 json-schema 中支持 reference,使用方式为在 Object 中使用关键字 $ref,然后值为对应 Object 的定义,需要注意的是,这个 Object 的定义需要在同个 Object 的 definitions 的 value 中,示例为:

这样,对于 Post 这个 Schema 就清晰多了。

这些就是 json-schema 一些常见的用法,通过这些用法的组合,足以让我们应对大部分的场景。如果当你遇到应对不了的场景的时候,别慌,可以去看看 schema 规范:json-schema,这份规范不复杂,可以较快得找到你需要的内容。

json schema 校验

当我们把 schema 定义好了之后,是时候尝试在代码中使用一把了,我这里使用的还是 Python 编程语言,这里我不能说使用任何编程语言都可以,根据我查找过程中的一些观察,似乎除了 Python,还有 Java 我是明确知道支持的,至于其他语言我就不太清楚了。

在 Python 中,首先第一步我们肯定是离不开安装依赖的 Library 的,肯定是老方法,直接用 pip 安装了,有简单的方式为什么不用呢:

$ pip install jsonschema

然后使用过程也是极其简单,下面这是一个针对我们刚才的 schema 的验证代码,可以一直执行尝试一下:

然后执行一遍看看,结果肯定是:

$ json is ok!

假设我们修改一下 json,看看不 ok 的时候又是什么情况?如果你试了,你肯定会发现不会输出 "json is invalid!" 这个错误,反而是直接抛出了异常,但是异常的内容又很多,非常得详细,有时我们不需要知道这么多,所以为了简略处理,我们需要对 validate 这个函数有所了解,这里对函数原型做一个简单的观看:

这里讲了可能抛出两种异常,分别是 :

ValidationError

SchemaError

所以我们在做开发调试的时候需要注意一些,如果是我们的 Schema 都编写错了,那么无论验证什么 json 必然都是会抛出异常的,这个坑是值得注意的。然后我们再看下 ValidationError 这个异常有啥内容:

可以发现其实这两种异常都是相同的属性,所以我们将他们的内容都打印出来看看:

message: 'hello' is not one of ['PostStatus.PUBLISHED', 'PostStatus.DELETED', 'PostStatus.DRAFT']

path: deque(['status'])

cause: None

context: []

instance: hello

schema: {'enum': ['PostStatus.PUBLISHED', 'PostStatus.DELETED', 'PostStatus.DRAFT'], 'type': 'string'}

schema_path: deque(['properties', 'status', 'enum'])

parent: None

ok,这样我们就很清楚每个字段表示的含义了,同时就可以在开发的时候根据自己的需要使用对应的字段了,一般情况下我建议直接使用 message 就可以了,所以最后示例代码修改成了:

总结

在本文中,我尝试以一种比较简单的方式对 json 的 schema 定义进行了一个介绍,同时,也一步步得对一个简单的示例进行扩展,最后使用 Python 编程语言对这个 Schema 进行验证。json 的使用在日常的开发中极其常见,而且因为其不错的灵活性,给我们开发带来了很大的方便;但是,在享受方便的同时,也经常给我们带来的意想不到的 BUG,所以,对于一些比较重要的出入口,不妨加上一个 Schema 校验,让程序运行得更健壮些。

json schema多种形式_Json Schema相关推荐

  1. json schema多种形式_Json Schema简介

    1. 引言 什么是Json Schema? 以一个例子来说明 假设有一个web api,接受一个json请求,返回某个用户在某个城市关系最近的若干个好友.一个请求的例子如下: { "city ...

  2. json schema多种形式_JSON Schema 简介

    在前后端分离架构下,JSON 格式被广泛用于前端的数据交互,并成为事实上的规范,但前端在编写表单的过程中,依旧对着字段和后端进行 CRUD,这其中的效率有可能提升吗?有什么规范能通用解决表单类的中后台 ...

  3. java schema校验_Json Schema 校验json,java代码示例

    Json Schema 校验json,java代码示例 1.json schema 入门请参考下面两篇博客 1.1Json Schema 快速入门 1.2Json Schema 简介 2.java代码 ...

  4. json schema多种形式_JsonSchema使用详解

    JSON Schema是一个用于验证JSON数据结构的强大工具, 我查看并学习了JSON Schema的官方文档, 做了详细的记录, 分享一下. 我们可以使用JSON Schema在后续做接口测试中做 ...

  5. Oracle Schema Objects(Schema Object Storage And Type)

    One characteristic of an RDBMS is the independence of physical data storage from logical data struct ...

  6. 一句话回复:关于'SqlMembershipProvider' requires a database schema compatible with schema version '1'...

    一个朋友说他建立好asp.net需要的membership-role关系后一直正常,后来运行了脚本,再运行时出现类似如下的错误 The 'System.Web.Security.SqlMembersh ...

  7. Creating schema using Saiku Schema Designer

    原文地址: http://wiki.meteorite.bi/display/SAIK/Creating+schema+using+Saiku+Schema+Designer Created by T ...

  8. json schema多种形式_什么是JSON Schema?

    什么是JSON Schema? 如果你曾经使用过XML Schema,RelaxNG或ASN.1,那么你很可能已经知道什么是JSON Schema,并且可以跳过本文的阅读.如果你是头一次听说,或者听过 ...

  9. json schema多种形式_什么是JSON Schema?及其应用方式......

    如果你曾经使用过XML Schema,RelaxNG或ASN.1,那么你很可能已经知道什么是JSON Schema,并且可以跳过本文的阅读.如果你是头一次听说,或者听过过这个词汇但不了解,那么你来对地 ...

最新文章

  1. 2018年IT市场最大的技术趋势和热点预测
  2. 通过PXE网络安装ESXI6
  3. HTTP 各版本特点与区别
  4. BW对于SAP SD模块有哪些作用
  5. 参加智能车大赛还是电赛?在做电磁炮中我找到了答案
  6. 机器学习实战(五)——Logistic 回归
  7. ASP.NET Core on K8S深入学习(6)Health Check
  8. 【转】QGridLayout 详解
  9. python3 在线工具_Curl转python在线工具
  10. 2684 亿背后的虚拟化技术:双 11 All on 神龙 | 问底中国 IT 技术演进
  11. ReflectionZ_测试_01
  12. c#中跨线程调用windows窗体控件
  13. SHELL中如何获得指定字符的位置及正确的截取动作
  14. cad2012打开后闪退_windows7打不开CAD2012出现闪退的处理方法
  15. 云运维拓扑图_云平台网络拓扑图
  16. Oracle 数据库认证考试
  17. Eclipse jdt 格式化java代码
  18. linux查看共享内存文件,linux 共享内存
  19. Deliberated Domain Bridging for Domain Adaptive Semantic Segmentation
  20. 简单、强大的swig.js

热门文章

  1. fastadmin操作中添加自定义按钮,点击弹出表格
  2. 中国手机市场销售额破万亿,二手手机的春天来了?
  3. JavaScript -- Enumerator
  4. exp4恶意代码分析实验报告-20202127
  5. P7103 「C.E.L.U-01」族谱树 (dfs 树形dp
  6. Android:Clipboard剪切板简单的使用
  7. 八天 自定义控件 使用贴图加载图片非原图片大小 decodeResource
  8. Qcom_Sensor(九)--- 之 aDSP端Sensor Driver流程
  9. 字符分类的函数(比如大写字母转小写的函数)
  10. Words for Games