SwaggerHub for VS Code:一个开发者如何将需求转化为酷炫的API设计新扩展

  2020年11月6日

使用 SwaggerHub 的最大好处之一是接触到各种 API。它们无处不在!我们自己也使用它们来编写记录我们正在使用的 API 的应用程序!我是 SwaggerHub 的前端开发人员,这意味着我主要以消费者的身份接触 API——通过成为第一方用户,我帮助塑造了我们 API 的成果。

作为一名前端开发人员,我选择的 IDE 是 Visual Studio Code。它速度快,整洁,而且作为一名 JavaScript 开发人员,它用 JavaScript 编写也特别方便。如果我对某个地方不确定,我可以查看其开源内部结构,了解其运作方式。

以上都是这篇博客核心主旨——VS Code 和 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 和域。

树视图

VS Code 的用户界面是严格且统一的。这种严格性是它最好的优点之一,因为扩展程序以可预测和可靠的方式运行。用户体验总是很棘手,但 VS Code 中既定的扩展设计语言意味着,如果你逻辑地放置某个东西,最终用户很可能会找到它,因为他们可以依赖预先存在的设计语言。

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

VS Code API 最初令人望而生畏,但经过一段时间后会逐渐变得易于理解。根据您所使用的功能,文档的清晰度可能差异很大。API 本身很清晰,但其工作原理的描述可能很模糊,并且大部分是由现有示例组成的——这些示例在力求简洁的同时,融入了 API 中大量的其他功能。您最终可能会实现一些您认为重要但实际上并非如此的功能。

就我们的目的而言,显然我们需要一个分层列表——文件夹、文档和版本,它们分为“API”部分和“域”部分。

初始化树视图很简单

我们创建新的树视图,并将其提供者绑定到全局对象,以便在整个应用程序中引用它们。提供者本身是围绕核心功能的类封装器。我们对 API 和域进行了区分,由于它们是我们唯一的区分,为了简单起见,我们向构造函数传递一个布尔值。

这里需要注意的一个重要事项是 onDidChangeTreeData 事件。当我们想要拉取更多数据时,可以触发此事件来刷新树视图。

接下来,我们用数据填充树视图。我们将使用的组织 API 在我们的设置中定义为一个字符串数组,但我们有一个小的消息传递包装,它需要一个异步操作。

生成我们的 API 列表很简单。我们获取组织,提取定义元数据,然后遍历数据集,构建我们的树。

树分支叶子的顺序构建自然而然地快速简便。返回扁平化的结果为树视图提供了显示我们所有可用 API 和域所需的完整数据集。

上下文菜单

使用 VS Code 意味着总能发现新的可玩之处。该工具的几乎每个方面都可以附加或利用某种扩展功能。当需要添加一些状态更新功能——例如更改可见性、发布/未发布等——最初的方法只是简单地利用命令面板。

这是大多数没有直接一对一 UI 的扩展功能的传统归宿,因为它基本上是 VS Code 的命令行。但我认为这种功能应该有比命令面板更好的用户体验。在 VS Code 中构建扩展的很多工作在于弄清楚每个功能应该放在哪里,以及为什么放在那里。我将命令面板视为最后的手段,非常像一种“暂时将就一下”的情况。

我一直在关注的一个议题是在编辑器的右键菜单中添加子菜单。如果 API 可用,一个浮动子菜单将是放置元素的完美上下文位置。VS Code 开源仓库中第一个讨论此问题的帖子来自 2016 年:https://github.com/microsoft/vscode/issues/9827。这显然是有用且需要的功能,它将帮助我们摆脱这个用户体验困境,但显然进展不大。

快进到 2020 年 9 月的 1.50.0 版本发布,子菜单 API 终于可用了——距离最初的请求已经过去了 4 年。对于 SwaggerHub 扩展来说,这真是完美的时机!

实现更新很简单,因为新的 API 非常直观。

首先,您需要建立一个具有唯一 ID 的子菜单部分

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

添加一些逻辑来指示菜单何时显示——例如,我们不希望它在 YAML 以外的任何文件上显示——并按部分对项目进行分组。当项目在各自的部分中时,会自动添加一个分隔符,以使所有内容更具可读性。

然后简单地将菜单绑定到正确的贡献点,在本例中是 `editor/context`

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

限制操作出现在命令面板中有其优缺点。通过用户界面中的功能,有清晰的用户路径可循。但通过命令面板中的命令,则有一种“高级玩家”的氛围,您可以使用组合键完成所有操作。

我相信随着人们开始试用,我们将来会对此进行迭代。软件开发中最激动人心的部分之一就是人们尝试将您的软件推向您意想不到的方向。我确信这个扩展未来会有很多这样的情况!

预览

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 内容的一种方式,让您可以访问外部世界和自定义用户体验。这里有很多可能性,看起来是我们在其中渲染 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 实例时,可能会出现时序问题,即在库加载完成之前,转换后的规范 JSON 已经传输到 WebView。我尝试了调整时序和等待加载消息等方法。但最终,我决定采用静态加载方法,这会增加初始扩展大小,但可以消除任何性能或时序问题。

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

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

VS Code 扩展以 .VSIX 文件形式交付——这基本上就是花哨的 zip 文件——并且只包含一小部分代码库。我们使用 webpack 将核心扩展打包成一个文件,但静态资源则存放在静态文件夹中。由于这些文件夹的位置因机器而异,我们需要为每个资产生成一个 VS Code 特定的 URI。然后,这些 URI 可以在后续的任何脚本或样式调用中使用。

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

将规范发送到预览窗口也非常简单,因为 VS Code API 用于向 WebView 发布和接收消息的功能虽然简单,但很实用。

有了 `previewWindow` 句柄和作为全局对象存储的内容以便在其他地方访问,我们只需使用 `postMessage`

我们必须首先使用出色的 js-yaml 库将 YAML 转换为 JSON——这是我们整个行业广泛依赖的东西——然后将其传输过去。

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

`setState` 代码是索引中其他状态管理代码的后续,它允许我们保留最后查看的规范,即使预览窗口移到后台。

收到消息后,我们只需将其发送到独立的 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

© . All rights reserved.