
大约三年前,2022 年初,早上 6 点,我坐在办公桌前,双手抱头。我非常确信这次一定能成功,我坚信自己做得不错。但可惜的是,这次只是换了一种失败的方式。
摆在我面前的问题是每个工程师在完成这项任务之初都会遇到的问题:
“这能有多难?”
事实证明,这真的很难。比我预想的要难很多。
到底是什么这么难?
我说的是构建一个能够完全理解 OpenAPI 的引擎、框架和平台。表面上看起来,这很简单,对吧?那不过是 YAML
或 JSON
格式的描述语言,能有多难?
最近,我一直在读 Robert Nystrom 所著的 Crafting Interpreters 一书,受益匪浅。他在引言中指出:
每有一种成功的通用语言,就有一千种成功的小众语言。过去,我们称它们为“小语言”,但术语经济的膨胀催生了“特定领域语言”这一名称。这些语言是针对特定任务量身定制的。想想应用脚本语言、模板引擎、标记格式和配置文件。
然后,他列举了 Make
、XSLT
、SQL
、JSON
、BASH
、YAML
、HTML
等例子。
这个类比非常贴近生活。从中我们可以了解一个根本问题,就是为什么只要超出最简单的用例, OpenAPI 就会让如此多的工程师感到棘手。
OpenAPI 不仅仅是一种语言,它还是一种由多种其他语言组成的语言。这种复杂性使得事情开始失控,例如:
YAML 支持锚点、别名和有序列表。
JSON 既不支持锚点也不支持别名,而且不保证顺序。
OpenAPI 3.0 使用一种不兼容的 JSON 模式变体。
OpenAPI 3.1 使用标准化的 JSON 模式。
JSON 模式本身就是一个复杂的标准。
JSON 指针可以是本地、远程、绝对或相对的。
这还只是 JSON
我们首先想到的往往是:“我可以把 JSON 数据解析成一些数据结构"。
开始时一切顺利,直到出现重复。然后,规范中出现了引用(JSON 指针),你的代码突然就崩溃了。模型不再工作。
现在,工程师需要一个查找表或哈希表来索引引用并将它们拼接在一起。当指针形成直接或间接循环时,循环引用会导致无限循环或堆栈溢出。
我们突然意识到,我们基本上是在为一种编程语言编写解释器和编译器,而不是一个简单的解析器。而编写一个编译器是很困难的。就在这个节骨眼上,大多数人放弃了,转而找一个库来处理这一切。
在尝试了很多方法后,他们最终选择了一个基本可行的方法,但仍然感觉不够完备。
三思而后行
大约 18 个月前,我开始着手构建一个可视化导航系统,用于探索这个由文件组成的网络中的庞大引用图。
我需要一个超级强大的底层 API 来组织、导航和挖掘引用、文件、目录和关系。当前采用的机制太有限了,于是我想到了 “rolodex”:一个设计过度的复杂系统,可以在庞大的文件网络中查找指向任何地方任何东西的指针。

在图中查找单个节点并不简单
rolodex 是一个索引卷轴,在一个地方包含了指向所有东西的所有指针。在 libopenapi 中,它看起来就像一个又大又重的机器。我花了大约三个月的时间才将其构建到现有的代码库中,并在没造成任何破坏的情况下将其连接了起来。
最后,它的功能和以前差不多。这么多的工作,就为了这么一点眼前利益?
方法是这样的
为了展示这项工作的强大和价值,我想提请大家注意 OpenAPI Doctor 及其中一个最新、最强大的功能。
加载 OpenAPI Doctor 时,可以看到 bump.sh 中的 Train Travel API 示例。

可点击的引用,轻松跳转到文档
现在,所有引用都显示为绿色(常规)或黄色(多态)。将鼠标悬停在某个引用上,它就会高亮显示,并显示一些元数据。如果按住 Command/Control 键并单击,就会直接跳转到规范的相应位置。
现在,浏览规范变得容易多了。我想要这个功能已经想了很多年了。
让我们再深入一些
让我们下载 Redocly 的 OpenAPI 入门示例。
前往 GitHub,点击绿色的“代码”按钮,然后点击“下载 ZIP”。

下载整个库的 zip 文件
接下来,打开 OpenAPI Doctor,点击蓝色的“导入”按钮。有两个选项:通过 URL 导入或上传 ZIP,选择上传 .zip 或 .tar 并选择刚刚下载的 ZIP 文件。

上传从 github 上下载的 ZIP 文件
Doctor 会读取 ZIP 文件,检测其中的 OpenAPI 文件,如果有多个输入文件,则会让你选择加载哪一个。
然后,它会打开 rolodex 面板,显示构成 OpenAPI 规范的整个文件系统。文件夹可以展开,文件可以点击,问题或参考资料都可以立即显示出来。

Rolodex 多文件规范面板打开
这样,你就可以在每个文件的上下文中查看违规情况,即使所有内容都还是一个大图的一部分。
你不仅可以跳转到外部引用(如其他文件中的 JSON 指针),还可以实时查看和诊断它们。
即使是图中引用的 Markdown 文件或示例代码也能无缝集成。

探索分散的、爆炸图一样的规范更简单了
只有引用过的文件才会加载到 rolodex 中。请注意,除了规范文件外,其他文件都不会显示。
销毁它
当你准备好重新开始时,点击 “ Nuke Workspace ”选项(已禁用的导入按钮旁边的核图标)。这样就能将所有内容清除干净——无法撤回。

全部销毁
然后重新导入同样的内容,但这次使用的是 Redocly OpenAPI 规范的 URL。除了目录结构现在是规范的完整远程路径,而不是 ZIP 文件的结构外,其他地方保持不变。
让我们上点难度
Redocly 的 OpenAPI 入门示例是一个简单实用的例子。
OpenAPI 毁灭者
但如果我们想看一个特别大的规范呢?一个怪物。我们请 Doctor 来读一读DigitalOcean OpenAPI规范吧。
它有 1 600 多个文件,数十万个引用。它能摧毁大多数工具,但不包括 Doctor。
将 Digital Ocean OpenAPI 规范的 URL粘贴到 Doctor 中,它就能吃下整个图。

吞下这个来自互联网的怪物
给它几秒钟的加载时间,再给浏览器一两秒的渲染时间,你就成功了。

研究下这个被 Doctor 打败的怪物
巨大的挑战
现在,尝试将 DigitalOcean 规范导入其他 OpenAPI 编辑器或工具。
如果你能找到一个:
不崩溃
不失败或出错
实际显示远程文件系统
允许上下文探索和调试
我就请你和你的家人吃饭。
本文最初发布于 quobix 的个人博客。
声明:本文为 InfoQ 翻译,未经许可禁止转载。
原文链接:
评论