SwaggerHub for VS Code:开发者需求如何成为 API 设计的酷炫新扩展

  2020 年 11 月 06 日

使用 SwaggerHub 最棒的事情之一就是接触 API。它们无处不在!我们自己使用它们来编写记录我们正在使用的 API 的应用程序!我是 SwaggerHub 的前端开发人员,这意味着我主要作为消费者接触 API – 我通过成为第一方用户来帮助塑造我们的 API 的结果。

现在,作为一名前端开发人员,我首选的 IDE 是 Visual Studio Code。它速度快,整洁,而且作为 JavaScript 开发人员,它用 JavaScript 编写也非常方便。如果我不确定某些事情,我可以查看开源内部结构,看看是什么让事情运转起来。

这都是本文的核心前提:VS Code 和 SwaggerHub。你看,作为 SwaggerHub 上消费 SwaggerHub API 的前端开发人员,我的自然倾向是在 VS Code 中读取、使用和处理这些 API。但过去这总是一件乏味的事情。

如果我不想丢失上下文,我必须下载 YAML,在编辑器中打开它,并很快发现自己与我的同事开发者所做的任何更改不同步。没过多久,我就完全放弃了这个方法,坚持在一个屏幕上打开 SwaggerHub,在另一个屏幕上打开 VS Code。

尽管这很实用,但我一直认为应该有更好的方法。因此,在集思广益我们一年一度的黑客马拉松的想法时,我想为什么不将两者结合起来,为 VS Code 编写一个与 SwaggerHub 完全集成的扩展

我们已经为任何拥有 SwaggerHub 帐户的人提供了公共 API,那么为什么不将其引入 IDE 呢?当时,VS Code API 似乎有点难以理解,无法在黑客马拉松期间掌握(事实证明,我后来是对的),所以这个想法在那次活动中没有实现。但它一直在酝酿。

我们在 SwaggerHub 中有停工期的情况很少 – 总是有新功能要构建 – 但在一个冲刺中,我们有时间在个人项目上工作几天,这有点像迷你黑客马拉松。我们大多数人都有我们想对 SwaggerHub 做的小型热情项目或改进,但很少有时间。所以当机会来临时,我双手抓住了它,开始工作。

多亏了我们的公共 API,许多功能的边界是已知的,我只能构建 API 中可用的内容。从这些限制中,扩展可以提供的功能类型很快变得清晰起来,我需要解决的第一件事是如何显示 SwaggerHub 的核心:组织、API 和域。

TreeView

VS Code UI 是僵硬和统一的。这种僵硬是它最好的优点之一,因为扩展以可预测和可靠的方式运行。UX 总是很棘手,但 VS Code 中已建立的扩展设计语言意味着,如果你将某些东西放置在逻辑上,最终用户可能会找到它,因为他们会依赖预先存在的设计语言。

左侧是 TreeView 容器。这是所有扩展的主要激活元素的栏。然后是我们拥有辅助扩展功能的 TreeView 本身。最后,我们拥有主编辑器。提供我们的组织、API 和域列表的逻辑位置是在 TreeView 中,其风格模仿文件浏览器的树结构。

VS Code API 最初令人望而生畏,但经过一段时间后会逐渐开放。根据你正在使用的功能,文档的清晰度可能会有很大差异。API 本身是清晰的,但对事物工作方式的描述可能含糊不清,并且其中大部分由预先存在的示例组成 - 虽然试图简洁,但混合了来自 API 的许多功能。你最终可能会实现你认为很重要的事情,但实际上并不重要。

出于我们的目的,很明显我们需要一个分层列表 - 文件夹、文档和版本,在“API”部分和“域”部分之间拆分。

初始化 TreeView 很简单

我们创建新的 TreeView,并将它们的提供程序绑定到全局对象,以便可以在整个应用程序中引用它们。提供程序本身是核心功能周围的类包装器。我们有 API 和域之间的区别,由于它们是我们唯一的区别,为了简单起见,我们将布尔值传递给构造函数。

这里要看到的重要事情是 onDidChangeTreeData 事件。这是我们可以在想要拉取更多数据时触发以刷新 TreeView 的事件。

接下来,我们使用数据填充 TreeView。我们将使用的 API 的 orgs 在我们的设置中定义为字符串数组,但我们有一个小的消息包装在其中,这需要一个异步操作。

生成我们的 API 列表很简单。我们获取 orgs,拉取定义元数据,并通过数据集进行循环,构建我们的树。

树枝叶子的顺序构建自然而快速。返回扁平化的结果使 TreeView 获得了显示我们所有可用 API 和域所需的完整数据集。

上下文菜单

使用 VS Code 意味着总是会发现新事物可以玩。该工具的几乎每个方面都可以附加或利用某种扩展功能。当需要包含一些状态更新功能(更改可见性、已发布/未发布等)时,最初的方法是简单地利用命令面板。

这是大多数没有直接 1:1 UI 的扩展功能的传统所在地,因为它基本上是 VS Code 的命令行。但我认为,这种功能必须有比命令面板更好的 UX。在 VS Code 中构建扩展的许多工作是弄清楚所有内容应该放在哪里,以及为什么应该放在那里。我认为命令面板是最后的方法,并且非常像是“现在这样就可以”的情况。

我一直在跟踪的一个线程是关于向编辑器中的右键单击菜单添加子菜单。如果 API 可用,飞出式子菜单将是放置元素的完美、上下文的地方。关于此的开源 VS Code 存储库中的第一个线程来自 2016 年:https://github.com/microsoft/vscode/issues/9827。它显然是有用且需要的功能,并且它可以帮助我们摆脱这种 UX 困境,但显然事情并没有进展太多。

快进到 2020 年 9 月的 1.50.0 版本,子菜单 API 终于可用了 - 在最初请求 4 年后。对于 SwaggerHub 扩展来说,真是太完美的时间了!

实现更新很简单,因为新的 API 很直接。

首先,您需要使用唯一的 ID 建立一个子菜单部分。

然后,在菜单的贡献点内为该 ID 创建一个相关的部分。

添加一些逻辑来指示菜单何时应该显示 – 例如,我们不希望它在 YAML 之外的任何内容上显示 – 并按部分分组项目。将项目放在它们自己的部分中时,会自动添加分隔符以使所有内容更具可读性。

然后,只需将菜单绑定到正确的贡献点,在本例中是编辑器/上下文。

我喜欢在这些情况下做的一件事是,阻止选项出现在命令面板中以减少干扰。这就像将您的命令添加到 commandPalette 贡献点,并将“when”的值设置为“false”一样简单。

限制操作不出现在命令面板中有利有弊。通过 UI 中的功能,有清晰的用户路径可遵循。但是,通过命令面板中的命令,会有一种“游戏高手”的感觉,您可以使用按键组合执行所有操作。

我相信随着人们开始尝试,我们将来会对此进行迭代。软件开发最令人兴奋的部分之一是当人们尝试将您的软件推向您意想不到的方向时。我相信这个扩展程序将来会有很多这样的情况!

预览

API 开发的一半是编写 API – 另一半是探索它作为消费者将如何工作,以及它将如何被读取和分发。在 SwaggerHub 中,我们在 Swagger 开源的朋友开发了出色的 Swagger UI 项目:https://github.com/swagger-api/swagger-ui/

在 SwaggerHub 中,我们使用这个项目和相关的 Swagger 编辑器来支持我们的 API 开发平台。它们是非常强大的工具,验证和显示引擎都是一流的,因此我们很高兴将它们纳入其中。我也希望将这种卓越性带入我们的扩展程序,并通过让用户在 VS Code 中直接使用 Swagger UI 的功能,将 API 开发提升到一个更高的水平。

我的首要任务是在 VS Code 中使用 WebView API。这实际上是一种在面板中显示 HTML 内容的方法,使您可以访问外部世界和自定义 UX。这里有很多可能性,看起来这是一个渲染 Swagger UI 的好方法。我曾经想过以某种神奇的方式原生引入 Swagger UI npm 库,并使其在 VS Code 内工作。但是,阻力最小的路径似乎是最佳方案,而且,Swagger UI 还有一个独立版本,适用于这种情况。

最初,面对各种可能性,我感到有些畏惧,但是有关建立 WebView 容器的出色文档将我引向了正确的道路:https://vscode.js.cn/api/extension-guides/webview

从外部来看,我意识到我需要创建一个可以静态加载的 HTML 包装页面,然后从外部拉入 Swagger UI JS 文件。按照 Swagger UI 文档进行第三方安装,我的第一种方法是使用 unpkg:https://github.com/swagger-api/swagger-ui/blob/master/docs/usage/installation.md

虽然这很容易起作用,但在打开窗口以拉取远程文件时会出现延迟问题。当第一次创建并加载 WebView 实例时,可能会出现时序问题,此时转换后的 spec JSON 会在库加载之前被传递到 WebView。我尝试了时序更改和调整,以等待加载消息等。但最终,我决定采用静态加载的方法,这将增加初始扩展程序的大小,但会消除任何性能或时序问题。

首先,我们初始化预览面板。

接下来,我们需要为我们捆绑到静态文件夹中的 JavaScript 文件生成 VS Code 兼容的 URI。

VS Code 扩展程序以 .VSIX 文件形式交付 – 几乎只是花哨的 zip 文件 – 并且只有一小部分代码库。我们使用 webpack 将我们的核心扩展程序捆绑到一个文件中,但静态资源存放在一个静态文件夹中。由于这些文件夹的位置因计算机而异,我们需要为每个资产生成一个 VS Code 特定的 URI。然后,这些 URI 可以用于后面的任何脚本或样式调用。

生成 URI 后,我们需要读取静态存储的索引文件,并将嵌入的捆绑字符串(在 {{ }} 中轻松注意到)替换为新的 VS Code URI。然后,我们将修改后的索引管道传输到 webview.html 中,现在可以立即从磁盘加载 Swagger UI 了。

将 spec 传递到预览窗口也非常简单,因为用于在 WebView 之间发送和接收消息的 VS Code API 很简单,但功能强大。

有了 previewWindow 句柄和存储为全局对象的内容,以便在其他地方访问,我们可以直接使用 postMessage。

我们必须首先使用出色的 js-yaml 库将 YAML 转换为 JSON – 我们整个行业都广泛依赖它 – 然后将其管道传输。

从另一个方向来看,我们的 WebView 面板需要设置为接收我们的消息。这就像连接一个事件侦听器一样简单。

setState 代码是 index 中其他状态管理代码的后续操作,它允许我们保留上次看到的 spec,即使预览窗口移到后台。

收到消息后,我们只需将其发送到独立的 Swagger UI。

然后,我们可以在文本文档更改时触发此方法,从而允许从编辑器实时更新 Swagger UI。

重要的是,我们只更新我们想要的文档。因此,我们确保文本更改消息来自正确的位置,获取文档文本并进行更新。很简单!

该扩展程序还有更多内容 – 多得多!但这只是其中一些有趣的细节。开发此扩展程序是一次很棒的体验,不仅是在 VS Code 中构建方面,而且还在于使用我们自己的 API。我坚信“喝自己的香槟”。

在开发内容时,很容易忽略最终用户体验,因为您要处理各种输入,无论是工单、请求、策略等等。从构思到部署的距离可能很长,如果没有真正体验用户的生活,就很容易忽略一些事情。

我们发现,在从第三方角度积极使用我们的 API 时,我们采取了额外的措施来改进它并解决沿途的一些细微差别。VS Code 扩展程序有一个姊妹项目。一个 CLI 工具,允许通过命令行界面与 SwaggerHub API 进行类似的交互 – 对于 CI 集成非常有用! https://github.com/SmartBear/swaggerhub-cli

我们一起对 API 进行了测试,我们希望这能鼓励更多人使用我们的 API,并将 SwaggerHub 更深入地集成到他们的系统中。这里有巨大的潜力等待我们探索,我们已经有更多正在积极开发的功能,准备在完成后推出。

创建此扩展程序是一项爱的劳动,我们非常高兴能与世界分享它并获得反馈。这是漫长道路上的第一步,我非常期待看到人们如何使用该扩展程序,以及它在多大程度上改变他们现有的工作流程。

要了解有关新的 SwaggerHub for VS Code 扩展程序的更多信息或下载副本,请访问 Visual Studio Marketplace