為多個 API 建立文件入口網站

第一部分 - 初始佈局與設計
  2018 年 11 月 12 日

Swagger UISlateSpectacle 之類的專案提供了很棒的文件功能,但著重於呈現單一 API  —  但如果我們想透過單一入口網站,為多個 API 清晰地提供文件呢?

隨著支援公開 API 的團隊數量不斷增加,或是需要向其他團隊提供「內部目錄」的群體,讓使用者在同一個地方了解各種 API 如何協同運作至關重要。設計良好且維護完善的文件有助於提高採用率、強制執行服務使用的最佳實務,並且是呈現新功能的絕佳方式。

在本系列中,我們將探討如何使用 React.js 動態將 OAS 定義傳遞到 Swagger UI 來建立解決方案(第一部分)、客製化這個基本入口網站(第二部分),以及最終部署到外部主機(第三部分)。本系列的後續部分將著重於較小的功能 — 例如使用「逐步導覽」樣式頁面增強文件,或連線到私人託管的定義。SwaggerHub 將作為我們 API 規格的主機,儘管本系列稍後將探討載入它們的替代選項。

這些步驟適用於對 React 和 OpenAPI 有一定熟悉度的人,但對於剛接觸這些工具的人來說,應該也相當容易遵循。

最終入口網站的範本版本可在此處找到,以開始此專案,而執行的範例則可在 此處找到。

什麼是 OpenAPI、Swagger UI 或 SwaggerHub?

OpenAPI 規格 (OAS) 是 REST 定義標準,由 OpenAPI 倡議維護 — 屬於 Linux 基金會的一部分。此規格最近發布了 3.0 版本,並且在整個產業中的採用和支援持續增長。像 OAS 這樣的標準有助於推動「設計優先」或「定義驅動」的開發策略,讓利害關係人在深入研究程式碼之前規劃 API 及其功能。即將發生的變更和測試需求可以更早地傳達,因為存在每個人都應該遵循的計畫。

Swagger UI 屬於 Swagger 工具集,該工具集是一組支援使用 OAS 的開源專案。長期以來,它一直與定義並行使用,透過最小的設定快速提供互動式文件。我們將在我們的單頁應用程式中利用 Swagger UI 提供的節點套件。

SwaggerHub 是 SmartBear 從頭開始建置的平台解決方案,以大規模支援 OAS。它與由單一組織或團隊管理多個不同 API 的想法相得益彰,我們可以使用其後端根據需要將這些 API 載入到我們的文件入口網站中。透過使用像 SwaggerHub 這樣的工具,我們可以更新和定義要顯示給 API 使用者的「目前」規格,同時也支援正在進行的設計和開發。


環境設定

現在我們了解將要使用的工具,讓我們確保擁有建置專案所需的相依性。在本系列的稍後部分,我們將研究如何將其部署到外部主機,或在容器中執行 — 但現在讓我們讓它在本機執行即可。此處的目標是以盡可能少的組態來完成此操作,以便開放我們的部署選項,因此我們只需要一個開始的要求:NodeJS

執行 node -v 來確認您安裝的節點版本高於5.2.0,因為我們將使用 npx 來建立我們的初始起點。

我們將使用 create-react-app 專案作為起點,而不是組合整個 React 開發環境。這讓我們可以使用單一指令獲得所有相依性和基礎結構。

若要開始,請導覽至將容納專案的父資料夾,然後執行 npx create-react-app oas-doc-portal

NPX 將負責建立基礎專案,您可以移動到新的專案資料夾並啟動預設應用程式,來確認一切順利。

$ cd oas-doc-portal
$ npm start

react_default.JPG

如果所有內容在瀏覽器中正確呈現,我們可以繼續將其連線到我們的定義儲存庫。

這也是將專案連線到您選擇的 GIT 儲存庫系統並進行初始推送的好時機。

轉譯單一規格

在進行任何動態傳遞定義之類的冒險行為之前,讓我們先確定我們可以從遠端資源載入和轉譯單一定義。這將為我們提供一個堅實的起點,並且讓我們在不可避免地損壞某些東西時,能夠輕易地識別出來。本教學課程將使用Swagger Petstore 定義,可在此處取得:https://petstore.swagger.io/v2/swagger.json

所有魔法都透過 swagger-ui 節點套件發生,因此讓我們使用 ctrl+c 停止應用程式,並將其新增至我們的應用程式

  • 執行 npm install swagger-ui,將 swagger-ui 安裝到專案中
  • 開啟 /src/App.js
  • 在頁面頂端的 import 陳述式下方新增 swagger-ui。

為了避免稍後重新設定,我們可以在應用程式中新增我們的建構函式,並為 OAS 連結建立一個狀態。我們將使用新的 OAS 連結即時更新此值,因此它是保存參照的完美位置。這篇文章更深入地探討了 React 如何處理狀態。

我們透過傳遞 Swagger UI 定義連結來渲染文件。由於此連結即將動態更新,我們應利用 React 的生命週期來保持所有內容為最新狀態 — 在此情況下,componentDidMount 將會派上用場(我們會隨著需求改變稍後調整)。

  • 在我們先前定義的建構函式下方,加入以下程式碼

Swagger UI 元件支援許多不同的參數,具體取決於我們想要如何渲染它,但對於我們的初始用例

  • 我們正在告訴它在我們接下來將建立的 api-data 元素內渲染我們的文件。
  • 參考儲存在我們狀態物件中的 URL,告訴它從哪裡載入定義。

繼續移除 create-react-app 為我們產生的佔位符渲染元素,並將它們替換為我們新定義的 div 需求

現在,Swagger UI 將在頁面上尋找 api-data 元素,並在其中渲染我們的文件。如果我們啟動應用程式並重新載入瀏覽器,我們應該會看到先前的佔位符頁面現在有了 Swagger Petstore 的基本表示!

react_basic-(1).JPG

它並不好看,但資料確實存在 — 而且我們現在可以手動更新我們的 definitionLink 值,以取得新的 API 資料渲染。本質上,接下來的步驟將會嘗試將此作為應用程式本身的一部分來執行。

此時的應用程式應該看起來像


動態更新定義

我們入口網站的最終目標是顯示 API 清單,在每個 API 之間點擊,並在我們的主視窗中看到文件更新。為此,我們將在側邊欄中顯示清單,並在使用者點擊清單時更新 definitionLink 值。

第一步,我們需要考慮從哪裡提取我們的 API 清單。為了本教學的目的,我們將使用 SwaggerHub 作為我們的儲存系統來提供各種 API 定義。如果您還沒有 SwaggerHub 帳戶,您可以在此處註冊免費帳戶、建立組織並加入一些定義。或者,您可以使用本教學中提供的範例組織

現在我們有了 SwaggerHub 組織和託管在那裡的幾個定義,我們可以開始考慮將它們提取到我們的入口網站中。這一切都將由 SwaggerHub API 驅動,因此作為起點,我們將編寫一個新函數來處理我們不同的 API 呼叫,並避免重寫太多程式碼。

  • 在我們的應用程式中加入一個新的 swaggerhub 函數

此函數將允許我們在幾個不同的層級向 SwaggerHub 發出呼叫,並且應該足夠靈活以支援我們在後續建立時的新功能。接下來,我們想要查看取得 API 的「清單」。

SwaggerHub API 允許對組織發出請求,並且回應包含 API 名稱和指向其位置的連結陣列,這非常適合我們的用例。

讓我們使用 swaggerhub 函數並建立一個新的 getOrganizationData 呼叫。這將採用單一輸入參數,即我們組織的名稱,並將 SwaggerHub 的回應設定為 API 的狀態級別清單。

現在更新狀態物件以預期 definitionList。這也是加入稍後會用到的另一個鍵/值對的好時機,並且我們應該將這兩個新函數綁定到應用程式。

我們也在 getOrganizationData 呼叫中參考了一個組織,但尚未將該資訊儲存在任何地方。接下來,我們還會想加入一個子標頭和公司標誌,因此讓我們建立一個設定檔來儲存此資訊。

  • /src 目錄中,建立一個名為 organization_config.json 的新檔案
  • 將以下物件加入設定檔,並填入您組織的資訊
  • 接下來將設定檔匯入 src/App.js
  • 最後,建立一個 componentWillMount 函數來處理頁面載入時的資料對應

我們已經建立了處理取回 API 清單的區塊 — 現在是開始思考我們想要如何將該資訊呈現給我們消費者的時間了。接下來的幾個步驟將建立一個新元件 Sidebar,以及一個名為 apiLink 的新元素,它將在側邊欄內部填入。

  • /src 中建立一個新檔案 — Sidebar.js。側邊欄一開始會非常簡單,只有一個基本結構和一些我們儲存在設定檔中的顯示名稱資料
  • 在主要 App 的 render 區段中,更新以包含新元件 — Sidebar。我們也想在這個時候傳遞它需要的資料和函數
  • 請務必也將 Sidebar 匯入應用程式。我們也應該從 swagger-ui 模組中匯入 CSS 檔案,以稍微清理我們的文件檢視。我們稍後將探索如何自訂它。
  • 為了稍微清理瀏覽器中的內容,讓我們加入一些快速 CSS,以清楚地了解我們接下來要進行哪些變更,以及在何處進行變更。在 App.css 檔案中,我們可以開始組織我們的頁面

empire_nolinks.JPG

太棒了!我們有了側邊欄的基本結構(標頭和將會容納連結的主體)— 但我們缺少一個關鍵部分,即連結本身。我們已經透過傳入的 props 傳遞了我們需要的大部分資料,因此只需編寫一些邏輯來處理該資料並更新我們的狀態物件。

  • 建立一個新檔案 /src/APILink.js,並使用它來處理從側邊欄傳入的資料
  • 這裡有幾件事我們要求但尚未傳遞下來。首先,讓我們在 App.js 中建立 updateDefintionLink 函數,在建構函式中將其綁定,並將其傳遞到側邊欄
  • 現在我們需要將兩者連接起來,因此讓我們更新 Sidebar.js 以包含以下內容

新增了什麼?

  • 首先,我們正在驗證是否已載入組織資料,如果尚未載入,則使用 getOrganizationData 發出該請求。
  • 一旦有了 API 資料,我們就會對其進行迭代,並將其輸入到新元素 APILink 中,該元素將根據使用者的選擇處理更新我們的 definitionLink 元件。我們檢查它是否在 SwaggerHub 中「已發佈」,然後將連結推送到 apiLinks 陣列。
  • 最後,我們從 APILink.js 進行了新的匯入。

完美。如果我們現在重新載入頁面,我們應該會看到我們的側邊欄中填入了我們所有不同 API 的名稱!讓我們快速更新我們的 CSS 來清理它們

現在我們應該會看到所有連結顯示在左側,並且可以點擊。只有一個問題 — 文件元件實際上沒有更新!幸運的是,這是一個快速修復。現在,我們的 updateDefinitionLink 正在執行其工作(如果我們使用 console.log,我們可以看到 URL 已正確傳遞)— Swagger UI 只是不知道它已更新,因為我們將其置於生命週期階段中。

為了修復此問題,只需將我們先前的 componentDidMount 函數更新為 App.js 中的 componentDidUpdate,當我們重新載入頁面時,它應該會隨著每個新的連結選擇而更新!

example.gif


總結

此時,我們有一個功能正常(但非常基本)的 API 文件入口網站!我們可以繼續加入新的 API 版本或定義,在我們的後端變更發佈和取消發佈 — 而且我們的文件將始終保持最新狀態。

在本系列的下一部分中,我們將研究如何有效率地開始為側邊欄和 Swagger UI 元素設定樣式,以個人化文件,然後在最後一部分中部署到幾個不同的託管網站。

以下是我們此時應該擁有的最終程式碼。

感謝您的閱讀!正在尋找更多 API 資源嗎?訂閱 Swagger 電子報。每月收到一封電子郵件,其中包含我們最好的 API 文章、培訓、教學課程等等。訂閱