前端示範

用於測試和探索 API 的前端應用程式

您是否曾參加過「示範」,開發人員自豪地展示 API 中的 JSON 輸出畫面,而使用者卻感到困惑和分心,無法理解任何內容?您是否曾嘗試在開發中使用 API,卻對尋找正確的 JSON 酬載和標頭咒語感到沮喪,無法測試功能?前端示範是一個簡單的 UI,提供基本功能來展示和探索此類 API。

2023 年 8 月 23 日


Photo of Matteo Vaccari

Matteo 是 Thoughtworks Italia 的開發人員和技術負責人。當極端程式設計有助於團隊和企業取得成功時,他很喜歡。


動機

任何運作良好的開發團隊的核心實務之一,就是定期展示他們正在建置的產品中最新改進。如果產品有使用者介面,那麼示範自然會透過 UI 本身提供,甚至可以讓參加會議的利害關係人直接使用它。

但是,如果產品是 API 呢?我們通常建議後端和前端由同一個團隊開發,因為與兩個獨立團隊必須協調的情況相比,這通常會帶來更高的品質和更短的開發時間。不過,有時這是不可行的:有時後端 (API) 是由一家公司開發的,該公司透過該 API 向第三方銷售有用的服務存取權。範例包括:提供「付款閘道」API 的金融機構,讓電子商務網站可以從客戶那裡收到付款;或透過價格比較引擎呼叫的 API 與價格比較引擎介接的服務提供者。

在 API 沒有自然使用者介面的所有情況中,提供有意義的示範變得困難。有時,團隊會嘗試透過顯示 API 傳回的 JSON 程式碼來展示 API 的用法,但這不容易理解,特別是非技術利害關係人。而且讓業務利害關係人使用產品幾乎是不可能的。

在這些情況下,我們發現為 API 專用產品開發一個簡單的 UI 有益,特別是為了 API 示範的目的。UI 不需要花俏或特別好看,也不需要設定專用的建置;目的是讓它可以輕鬆顯示 API 用法。

這種示範前端的好處不限於在示範期間展示軟體;一旦你讓它可用,開發人員將使用它在將程式碼推送到儲存庫之前在他們的本地機器上測試新功能,而品質分析師、產品負責人和其他利害關係人將使用它在測試環境中測試產品。它也可以用於向可能對購買存取權感興趣的潛在合作夥伴展示 API 的用法。示範前端是一個持續給予的禮物。

實用建議

當示範前端在所有相關 API 可用的地方立即可用時,效果最好。例如,在 Spring Boot 應用程式中,你可以將靜態 HTML、CSS 和 JavaScript 資源放在 src/main/resources/public/testdrive 資料夾中,這樣就可以透過在瀏覽器中開啟,例如 https://127.0.0.1:8080/testdrive/ 來存取它們。最簡單的示範 UI 除了取代 Postman 之外,幾乎沒有其他作用

A screenshot of the simplest possible demo UI,          showing an input text area with an editable input JSON, and an output text area with the          response JSON from the API. The output text area has a green background to signify a successful         response

圖 2:使用者可以調整要求酬載、方法和路徑:回應出現在較低視窗中,以綠色表示成功的回應

A screenshot of the same UI, showing an error         response colored in pink, because of a missing parameter

圖 3:錯誤回應會以粉紅色標示輸出文字區域,讓使用者更容易發現

示範使用者介面會為指定的 API 端點準備一個有效的 JSON 請求,然後讓使用者手動修改請求以符合他們想要測試的內容,當使用者按下按鈕時,它將顯示回應,可能包含 http 狀態碼和任何相關的標頭。

儘管在這個階段我們仍然將 JSON 作為輸入和輸出顯示,但我們比 Postman 擁有相當大的優勢,因為我們可以使用自動化來擴充或修改建議給使用者的輸入 JSON 的靜態版本。例如,如果一個有效的請求應該包含一個唯一的識別碼,一小段 JavaScript 程式碼就可以產生一個隨機識別碼,而使用者無需執行任何操作。這裡的重點是,使用者介面允許快速測試,摩擦力最小。

製作像這樣的示範前端所需的 JavaScript 最少:目前的 JavaScript 已經足夠強大,無需特定的函式庫,儘管開發人員可能會發現使用 htmx、jQuery 甚至內嵌 React 等輕量級工具很方便。我們建議避免設定專用的建置,因為這會在執行 API 和透過使用者介面執行測試之間增加額外的步驟。理想情況下,我們唯一想執行的建置是 API 產品本身的建置。在想要測試某個東西和實際執行測試之間的任何延遲都會減慢開發迴圈。

此類使用者介面的自然演進是

  1. 新增產生不同類型輸入的設施;或許完全以適當的 HTML 表單取代 JSON 文字區域
  2. 解析並以易於理解的方式顯示輸出

例如,假設我們有一個與旅遊相關的 API,允許我們預訂航班,目的是為可以彈性調整日期的旅客找到最優惠的價格。我們可能有一個執行搜尋並傳回價格組合清單的初始 API。輸入的 JSON 可能如下所示

{
  "departure-airport": "LIN",
  "arrival-airport"  : "FCO",
  "departure-date"   : "2023-09-01",
  "return-date"      : "2023-09-10",
  "adults"           : 1,
  "children"         : 0,
  "infants"          : 0,
  "currency"         : "EUR"
}

我們的示範使用者介面會在輸入文字區域中載入範例有效負載,讓使用者不必記住精確的語法。

A screenshot of another         demo page, for a fictitious flight search API, with a more complicated         payload

圖 4:實際的 JSON 有效負載往往很複雜

但是使用者可能需要變更日期,因為任何靜態的出發或抵達日期最終都會隨著時間流逝而失效,而且日期會變成過去,而變更日期需要時間,並且可能因為手動錯誤而導致進一步的時間損失。一個解決方案可以是自動修改 JSON 中的日期,例如將它們設定為未來 30 天。這將使執行 API 的快速「煙霧測試」變得非常容易:只要按一下「搜尋航班」並查看結果即可。

我們可以進一步探討:例如,有時我們可能想查看未來大約六個月的航班價格;有時是 3 個月,有時僅是一週後。提供一個使用者介面,讓使用者可以從下拉式選單中選擇,快速變更 JSON 酬載,是一件很酷的事。如果我們對其他輸入欄位提供相同的選項,例如機場代碼,我們就可以省去使用者查詢機場代碼的需要,這也能節省寶貴的時間。

The same page, with a few          dropdown menus that provide an easy way to update the payload

圖 5:加入 HTML 表單,自動調整酬載

上述使用者介面讓變更 JSON 酬載變得快速又容易,使用者幾乎不需要任何專業知識。仍然可以檢查產生的 JSON,而且如果使用者想測試 HTML 表單未涵蓋的案例,他們也可以直接變更 JSON。

航班搜尋 API 可以傳回一個價格矩陣,依日期而異,讓客戶選擇出發和回程航班的最佳組合。例如

The same page, now showing part of a complex         JSON response

圖 6:JSON 回應通常也很複雜

人類很難理解 JSON 中的價格矩陣,因此我們可以剖析 JSON,並將其格式化成一個漂亮的 HTML 表格。

Again the same page, now with an HTML         table, presenting the JSON response in an easier-to-read way

圖 7:剖析回應,並以易於閱讀的格式呈現

一個簡單的 HTML 表格可以讓技術使用者和非技術使用者輕鬆驗證 API 的結果。

常見問題

為什麼不改用 Swagger UI?

Swagger UI 滿足了與示範前端相同的優點:它可以立即使用,它定義在與原始程式碼相同的原始程式碼存放庫中;它由提供 API 的相同服務提供。與示範前端相比,它有一些缺點

  • Swagger UI 中的輸入和輸出酬載僅限於 JSON:你無法讓它更具可讀性。
  • 它對非技術使用者不友善。
  • 它只能提供靜態酬載;如果你需要在每次呼叫時提供一個隨機 ID 怎麼辦?如果酬載應該包含目前的日期怎麼辦?使用者必須記住手動修正酬載,而且他們需要知道如何修正。透過一點 JavaScript,你可以在示範前端中輕鬆自動提供這項功能
  • Swagger UI 不支援工作流程;透過示範前端,你可以按正確順序呈現要進行的呼叫,引導使用者。你也可以從一個呼叫的輸出中取得部分內容,並使用它們來準備工作流程中下一個呼叫的酬載

我們是否應該使用 npm 設定專用的建置?

如果您的前端使用專用的建置指令,則您的本地編輯-編譯-執行-測試迴圈中會有一個額外的步驟:這會讓您的迴圈變慢。它還需要您讓持續整合和交付自動化變得複雜:現在您的原始碼儲存庫會產生兩個成品,而不是一個;您必須建置兩個並部署兩個。由於這些原因,我不建議這樣做。如果您習慣使用「大型」前端框架,例如 Angular,您可能會驚訝於僅透過在內嵌 <script> 標籤中載入 jQueryReact 就可以完成多少工作。

我們是否在做客戶沒有要求的工作?

示範前端改進了產品的一些跨功能屬性,客戶可能會欣賞:至少是產品的可測試性和開發人員體驗,因此開發速度,但可能還有其他跨功能屬性會受到有用的影響。

讓我告訴您一個故事:一段時間前,我們參與了 API 產品的重寫。在該產品中,API 呼叫可能會導致對其他下游服務的數十次呼叫,並且每個下游呼叫都可能在 HTTP 意義上失敗,方法是傳回 HTTP 錯誤狀態碼,並且可能在邏輯上失敗,方法是在回應有效負載中傳回邏輯錯誤碼。由於那些數十個下游呼叫中的任何一個以不同的方式失敗都可能導致我們的 API 回應中產生不同的、意外的結果,因此很明顯,我們需要一種方法來快速查看我們的系統與下游服務互動時發生了什麼,因此我們使用所有下游服務互動的報告增強了示範前端,顯示對我們 API 的一次呼叫中每個下游呼叫的請求和回應。

示範前端最終成為一項殺手級功能,對產品的成功有很大的貢獻,因為它讓測試人員可以輕鬆除錯,找出呼叫為何未產生預期結果的原因。示範前端最終也應用於生產環境,讓內部使用者可以對來自產品客戶(也就是他們的合作夥伴)的呼叫進行疑難排解。客戶告訴我們他們很滿意,因為現在他們可以在幾分鐘內找出呼叫為何未如預期運作的原因,而舊系統則需要好幾天。

客戶並未明確要求提供示範前端,但他們在專案啟動時告訴我們,他們使用目前的系統時,很難找出呼叫 API 為何會傳回預期之外的值。我們為他們建置的示範前端,除了其他功能之外,也是針對他們告訴我們的問題所提供的解決方案。

進一步了解

API 端點通常用於連續使用,以支援某種自動化工作流程,或可能是由人類使用者進行的決策流程。在這些情況下,我們可以擴充示範前端,以明確支援工作流程。在某種程度上,示範前端可用於作為 API 使用者如何使用 API 的文件,或作為原型前端,供完整實作參考。

這個 git 儲存庫 中有一些範例程式碼可用於作為起點;螢幕截圖就是從中擷取的。


重大修訂

2023 年 8 月 23 日:發布