使用 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 的組織在我們的設定中定義為字串陣列,但我們有一個小段訊息包裝在其中,需要非同步動作。
產生我們的 API 清單很簡單。我們抓取自己的組織、提取定義元資料,然後在資料集中迴圈,建構我們的樹狀結構。
樹狀分支的葉的循序建構自然快速且容易。傳回扁平化的結果會為 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 以外的任何內容上顯示 – 並將項目按區塊分組。將項目放在各自的區塊中,會自動新增分隔符號,使一切更具可讀性。
然後,只需將選單綁定到正確的貢獻點,在本例中是 editor/context。
在這種情況下,我喜歡做的一件事是防止選項出現在命令面板中,以減少雜訊。這很簡單,只需將你的命令添加到 commandPalette 貢獻點,並將「when」值設為「false」即可。
限制動作出現在命令面板中有利有弊。透過 UI 中的功能,有明確的使用者路徑可遵循。但是,透過命令面板中的命令,則有一種「骨灰級玩家」的氛圍,你可以使用按鍵組合來完成所有操作。
我確信未來當人們開始嘗試這些功能時,我們會對此進行反覆改進。軟體開發最令人興奮的部分之一是當人們嘗試將你的軟體朝你意想不到的方向發展時。我相信這個擴充功能未來會有很多這樣的情況!
預覽
API 開發的一半是撰寫 API,另一半是探索它如何作為消費者運作,以及如何讀取和分發。在 SwaggerHub 中,我們在 Swagger 開源的朋友開發了出色的 Swagger UI 專案:https://github.com/swagger-api/swagger-ui/
在 SwaggerHub 中,我們使用此專案和相關的 Swagger Editor 來支援我們的 API 開發平台。它們是非常強大的工具,而且驗證和顯示引擎都是頂級的,因此我們很高興將它們整合進來。我也想將這種卓越性帶入我們的擴充功能,並透過讓使用者在 VS Code 中直接使用 Swagger UI 的強大功能,將 API 開發提升到更高的層次。
我首先考慮的是在 VS Code 中使用 WebView API。這實際上是在面板中顯示 HTML 內容的一種方式,讓你能夠存取外部世界和自訂使用者體驗。這裡有許多可能性,而且看起來是我們呈現 Swagger UI 的一個絕佳途徑。我曾想過要以某種神奇的方式原生引入 Swagger UI npm 函式庫,並使其在 VS Code 內部運作。但是,阻力最小的路徑似乎是最佳選擇,而且,Swagger UI 還有一個獨立版本,適用於這種情況。
最初,我對各種可能性感到畏懼,但關於建立 WebView 容器的出色文件讓我走上了正確的道路:https://vscode.dev.org.tw/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 可以立即從磁碟載入。
將規格傳送到預覽視窗也很簡單,因為用於在 WebView 中來回傳送訊息的 VS Code API 很簡單,但功能齊全。
有了預覽視窗控制代碼和儲存為全域物件以供其他地方存取的內容,我們只需使用 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。