关于OpenAPI和JSON模式的更新

492 阅读11分钟

2020-02-02更新JSON Schema草案2019-09已经发布了一段时间,经过反复斟酌,我们让OpenAPI的人合并了#1977,用于v3.1。这将使OpenAPI成为一个小的超集,而不再是一个子集/超集/边集。在这五个关键词中,有两个已经废弃了(nullableexample )。v3.1.0-RC1的最新估计是2月底,所以工具供应商应该着手升级对JSON Schema 2019-09和其他OpenAPI v3.1变化的支持。


现在API设计领域正在蓬勃发展,OpenAPI和JSON Schema工具正在认真成长。我在Stoplight.io的新工作让我对改善这一领域的热情有了渠道,整个团队一直在粉碎它。我们发布了一个新的API描述文档连接器(Spectral),一个该死的智能模拟服务器(Prism),以及一个惊人的OpenAPI和JSON Schema编辑器,名为Stoplight Studio。最后一个是非常特别的,是很多人多年工作的结晶。

我一直在谈论的设计优先的工作流程的大部分问题都得到了解决,这意味着你可以用免费的Stoplight工具来取代你的仓鼠驱动的docs/mocks/linting/governance之类的废话。

可悲的是,在API设计领域仍有一个巨大的问题,我们还没有设法解决。OpenAPI v3.0和JSON Schema仍然只是基本兼容,而这一点差异足以给很多人带来大问题:

我无法接受的是,OpenAPI/Swagger有自己的模式格式,几乎是JSON Schema,但又不完全是。这是为什么呢?t.co/6bMp8zp5gs

- peter_marklund (@peter_marklund)June 13, 2019

不久前,我在博客中谈到了这两种描述语言之间的分歧和不兼容,这主要是关于OpenAPI v3.0是JSON Schema草案5的 "扩展子集"。"扩展子集 "这一短语意味着它缺少一些东西,增加了一些东西,并改变了一些其他的部分。OpenAPI Schema对象不是JSON Schema,工具也不能互换,但人们认为它是

在过去的两年中,我的工作生活中大约有10%的时间是在试图向人们解释这个问题,并解决它所造成的混乱。在我的Twitter粉丝和Slack社区的100个样本中,38%的人幸运地从未注意到这个问题,而62%的人至少被咬过一次。遇到这个问题的人中,有一半人经常被咬。

在WeWork,我创建了一个解决方法,让人们为他们的数据模型编写实际的JSON Schema,然后通过Speccy内置的解析器命令将其转换为OpenAPI Schema对象(有OpenAPI味道的JSON Schema,但不是)。遗憾的是,自从我离开WeWork后,Speccy没有做任何功能工作,而json-schema-to-openapi-schema甚至没有得到合并的PR。

我们可以将json-schema-to-openapi-schema分叉,并在Stoplight上维护它,但我宁愿真正解决这个问题,而不是把开发人员的时间用于破解这个问题。

替代模式

OpenAPI倡议每两周召开一次会议,有一个叫做 "OpenAPI技术指导委员会 "的小组。有一段时间,人们讨论了由优秀的Darrel Miller倡导的 "替代模式"。这个想法是,OpenAPI v3.1将增加一个新的关键词alternativeSchema ,你可以指定schemaTye: jsonSchemaxmlSchema ,或其他各种相关的模式语言。

替代模式在2018年4月时听起来很不错。我每两周都会参加一个小时的电话会议,但当我在WeWork的事情变得糟糕时,我就推掉了,骑着自行车在火山上来回走了一个月。当我回到工作岗位上时,替代模式的提议已经演变成一个令人难以置信的复杂的东西,而且我认为对终端用户来说不是很有用,对工具供应商也很糟糕。

它允许以一种非常混乱的方式混合OpenAPI Schema和JSON Schema对象,这意味着JSON Schema关键字被应用于OpenAPI Schema对象的特殊关键字,本质上是对OpenAPI对象的 "额外验证",这...并不理想。对于任何感兴趣的人,我已经在OpenAPI规范repo上给出了建设性的批评意见,并且确实计划在接下来的几个月里,作为我在Stoplight工作的一部分,提出一个替代性的替代模式建议。

同时,我建议将AS推迟到OpenAPI v4.0,"通过可扩展的模式接口支持适当的JSON模式、XML模式、Schematron等 "是这个大版本的主题。那将是巨大的,但那将是巨大的。同时,我们可以使OpenAPI v3.1专注于完全解决JSON Schema的兼容性,而且是永远解决,在3.1.0.md Markdown文件中的措辞有一个完全兼容的改变。

OpenAPI v3.1中的JSON Schema对齐性

JSON Schema正在完成围绕$id$anchor 的一些工作,然后就可以给下一个草案打上标签了,已经完成了最新的草案!抛弃了旧的非标准的1-7版本模式,下一个草案有一段时间被称为8号草案,最新的草案被称为 "JSON Schema Draft 2019-09"。它没有重大变化,但大幅简化了很多语言,使JSON Schema规范更容易阅读。

有些人担心将OpenAPI v3.1与草案挂钩,但现在草案程序几乎已经完成。随着这个草案的出炉,还会有更多的草案,之后的草案预计会是相当于v1.0.0-RC1的东西。我们正在考虑我们与IETF和W3C的选择,他们可能希望考虑一些变化,但现在事情已经很接近了,到了坚持第5稿的程度,比升级到现代JSON Schema的任何感知的缺点要大得多。

对于OpenAPI、其工具供应商和这些工具的用户来说,升级将是简单的。在5和2019-09之间有两个 "破坏性变化",OpenAPI可以为其用户抽象出来:exclusiveMinimumexclusiveMaximum 。在5号草案中,它们是修改器,而现在它们是不同的值:

# draft 5
minimum: 10
exclusiveMinimum: true

# draft 2019-09
exclusiveMinimum: 10

OpenAPI v3.1可以很容易地支持两者,检测其是布尔值还是整数。那么OpenAPI工具供应商需要支持的唯一变化就是支持各种新的JSON模式关键字,比如:

  • propertyNames (允许的属性的速记数组)
  • const (像 ,但只有一个值)enum
  • examples 而不仅仅是example
  • if / then / else allOf/oneOf上的糖

在JSON Schema听取其用户群的反馈并添加这些新功能的同时,我们也一直在努力接近OpenAPI。JSON Schema增加了readOnlywriteOnly ,关键字,最近我把deprecated 纳入了2019-09。🙌

2019-09增加了词汇表,这是考虑到OpenAPI(和AsyncAPI)等项目而设计的功能。OpenAPI模式对象可以成为一个词汇表,扩展 "核心 "和 "验证 "词汇表,完全忽略JSON Hyper Schema,并为4个额外的关键字和2个 "修改 "的关键字描述行为:

  • nullable
  • discriminator
  • xml
  • example
  • exclusiveMinimum /exclusiveMaximum

向人们解释OpenAPI是JSON Schema的超集,要比解释 "扩展子集 "到底是怎么回事容易得多。

如果他们接受我的建议,废弃nullable ,改用type: ['foo', 'null'] ,改用example ,改用examples ,改用discriminator ,改用allOf ,那就更有意义了,因为大多数OpenAPI工具都不支持discriminator,它仍然让我们中的许多人感到困惑。

这将推动OpenAPI v3.1的用户使用普通的JSON Schema,正好赶上v4.0,他们可以真正使用JSON Schema,这些多余的关键字可以被遗忘。在新的 "替代模式 "中,甚至不需要尴尬的xml 关键字(或者如我所说,只是对schema 的新方法):

你使用OpenAPI v3.0来描述XML API吗?t.co/e8FgTCGxVL#… #openapi @OpenApiSpecRT for reach.

- Wandering Woodsman 🚴🔥🌍 (@philsturgeon)June 4, 2019

最主要的是,OpenAPI v3.1可以一劳永逸地解决主要问题:如果人们愿意,可以在OpenAPI中使用bog-standard JSON Schema,而不会在尝试使用OpenAPI不支持的JSON Schema关键字时出现奇怪的错误。这种情况将不复存在,而且不需要一个黑客工作法来将一个转换为另一个。

工具供应商也会很轻松,因为JSON Schema验证器可以取代手工滚动的OpenAPI验证器,其中许多都是过时的,或者是坏的。它们可以直接被扔进垃圾桶,而对少数额外关键词的支持可以作为预编程或第三方词汇进入JSON Schema验证器。在更少的工具上进行更多的团队合作,这是个梦想!

进展

那么,我们在完成这项工作方面进展如何?

早在6月份,OpenAPI TSC就在进行游戏,看看更新到现代JSON Schema会是什么样子,但接下来的聊天并不顺利。可能是因为我在塞尔维亚骑车,让自己处于热衰竭和中暑之间,但当我试图展示作为JSON Schema词汇表的OpenAPI时,事情就变得混乱了。

这个PR太混乱了,所以我做了另一个PR(#1977),重点是对规范的修改,我们可以在以后弄清作为词汇表的实现。

遗憾的是,大约在我完成这个PR的时候,每两周一次的电话会议在夏天休息了。 Darrel和我通过PR评论异步取得了一些进展,我在OpenAPI Slack上寻找反馈。有两个静态语言代码生成器工具的开发者提出了一些问题。他们关注的要点是,他们已经在努力支持动态有效载荷的关键字,如allOf (OAS2)和oneOf (OAS3),所以添加更多的东西,如 "类型数组"(如:type: ["string", "null"] )将是一个问题,尽管该关键字是长形式的oneOf,类型为字符串或null。

不用太深入地去研究它。JSON是一种动态数据格式,JSON支持的东西不能转化为简单的习惯性Java或C++。一个JSON API响应可能包含一个{ data: {} } ,它是一个单一的对象或一个对象的数组。一个对象可能会返回一个任意的用户生成的键和值的对象,这需要用patternProperties 或类似的方式进行通用描述。使用API演进的人可能已经把coordinates: "lat,lng" 从一个字符串改为数组。coordinates: ["lat", "lon"]废弃了字符串,但支持这两者,直到客户端有更新。

这些动态有效载荷可以在任何编程语言中处理,只是在静态语言中比较棘手。我理解这一点,但是考虑到在 "让工具供应商的生活变得更困难 "和 "让所有OpenAPI的用户(无论他们使用什么语言)都感到非常困惑 "之间的选择,前者应该是全票通过的,即使是我们工具供应商。

关于这个问题,下次再谈,但现在至少那两个有顾虑的人没有阻止V3.1的JSON Schema更新。他们正在关注一个叫做 "OpenAPI配置文件 "的概念,这个概念可能会发生,也可能不会发生,但无论如何都希望能让JSON Schema的更新取得进展。

现在,9月已经到来,电话很快就会再次启动。由于我们很多人都在2019年的API城,我们错过了周五的电话会议,但下一次电话会议应该会发生。我将避免中暑,这样我就不必在房间里旋转的时候尝试做演讲,希望我们可以合并#1977;让OpenAPI v3.1承诺支持现代JSON Schema作为一个轻量级的超集,而不是一个非常旧的草案的定制/子集/超集。🙌

2019-10-03更新JSON Schema 2019-09草案已经发布,而OpenAPI v3.1看起来很可能包含#1977--它带来了对JSON Schema 2019-09草案的全面支持。那么,OpenAPI v3.1何时发布?很难说,但有消息说可能会在几周内推出RC1,而更复杂的东西,如覆盖,很可能被推迟到以后的RC,或v3.2。事情看起来非常积极。

2020-02-02更新JSON Schema草案2019-09已经发布了一段时间,经过反复斟酌,我们让OpenAPI的人把#1977合并到v3.1。这将使OpenAPI成为一个小的超集,而不再是一个子集/超集/边集。在这五个关键词中,有两个已经废弃了(nullableexample )。v3.1.0-RC1的最新估计是2月底,所以工具供应商应该着手升级对JSON Schema 2019-09和其他OpenAPI v3.1的支持。