大多數開發者可能都用過 Postman,根據其官網的介紹:Postman 是一個用於構建和使用 API 的 API 平臺,簡化了 API 生命周期的每個步驟,提供更便捷的團隊協作,因此可以更快地創建更好的 API。這裡的 API,除了我們常用的 HTTP API 之外,還包括 Websocket(B ...
大多數開發者可能都用過 Postman,根據其官網的介紹:Postman 是一個用於構建和使用 API 的 API 平臺,簡化了 API 生命周期的每個步驟,提供更便捷的團隊協作,因此可以更快地創建更好的 API。這裡的 API,除了我們常用的 HTTP API 之外,還包括 Websocket(BETA),gRPC。本文中,我們將以最常用的 REST API 作為例子。
假設我們在開發一個類似微博的項目,你是一個後端開發人員,前端分為手機端和網頁端,而由於採用了 RAD 或者敏捷開發方法,你隨時需要將在開發環境測試好的最新的 API 改動發佈至測試環境(或 Stage 環境),併為測試人員或者前端開發人員提供最新的 API 文檔。下麵我們看看在這個過程中,Postman 能如何幫助簡化 API 聲明周期以及提供更便捷的團隊協作。
開發階段
在這個階段,不管後端使用什麼語言開發,最終開放的是 REST API 介面,在本文的示例中,我們使用 Jmix 框架開發基於服務的 REST API。Postman 的最基本用法,就是開發人員可以在這一步建立一個 API 集合(Collection),其中包含項目的所有 API,這裡我們創建了一個叫 Corp
的集合,包含所有功能的 API:
圖中重要的三個部分:
- API 集合
- 單個 API 的請求方式(POST)和請求地址
- 單個 API 請求體
到這一步為止,就是 Postman 的基礎用法了,我們創建一個 API 集合,而集合是支持導出的,可以導出為 JSON 文件,再發給其他同事,他們可以導入到 Postman 裡面使用。
使用變數做第一次優化
在上面的圖中,我們展示了集合中的第一個介面 - 獲取 Jmix 本地 token。而這個 token,我們需要在以後的每個請求中都用來做用戶認證。如下圖:
這裡有一個問題,就是 token 會過期,比如我們今天拿到的 token,可能明天就沒法再次使用了。而我們需要再次獲取 token,然後挨個複製到每個請求中嗎?這個未免太麻煩了。Postman 提供了環境變數的機制。有三種類型的變數,分別是:
- 全局變數(Globals):顧名思義,這裡定義的變數在所有集合的所有 API 中都可使用。
- 集合變數:在集合中,有一個
Variables
標簽頁,可以定義集合級別的變數,這些變數,只能用於集合內的 API。 - 環境變數:需要建立一個環境變數的集合,這裡面可以定義一組該環境內的變數,可以用在任何集合。後面我們會說到用法。
我們可以聲明一個名為 jmixToken
的集合變數存儲 token,至然後在請求中使用 {{jmixToken}}
的方式引用變數即可:
除了 token 之外,我們在 API 中使用的相同類型的參數也都可以聲明為變數,而變數可以用在請求的任何部分。例如,我們在發新帖的 API 中使用的請求體如下,我們分別使用了 Postman 提供的隨機生成 UUID 的 $guid
變數、集合中存儲測試用戶 Id 的 userId
變數,以及存儲我們博客地址 https://blog.abmcode.com
的 blogUrl
:
{
"postId":"{{$guid}}",
"userId":"{{userId}}",
"content":"歡迎訪問:{{blogUrl}}"
}
使用腳本進行第二次優化
經過了上面的第一輪優化後,我們的 API 裡面會多了許多變數。但是還存在一個問題,就是我們在拿到 token 後,仍然需要手動更新一下 jmixToken
這個變數,否則各個 API 仍然使用的是過期的 token。這還是有點麻煩。
好在 Postman 提供了測試腳本的功能,可以解決這個小麻煩,我們需要在獲取 token 的請求中編寫一個測試腳本,用於更新 jmixToken
,這樣我們一旦重新獲取了 token,就可以保證其他 API 使用的是最新的 token。
編寫代碼的位置如下圖所示,在 API 的 Tests
標簽頁。並且更貼心的是,Postman 在右側給了一些常用的代碼片段,點擊即可使用,例如,獲取全局變數、設置集合變數等。
測試腳本是 JavaScript 的,可能需要有一點 JS 基礎,具體每行的作用,請參考註釋。這裡我們對返回結果做了兩個測試,分別是驗證 HTTP 狀態碼必須是 200 以及檢測返回結果中必須包含 access_token
這個屬性。需要註意的是,這兩個測試如果有任意一個失敗,都將拋出異常直接退出 JS 的執行,此時不會走最後一句設置變數的語句:
// pm.test 表示這是一個測試。
pm.test("Set Global variable jmixToken", function () {
// 測試 1 - 返回狀態碼為 200
pm.response.to.have.status(200);
// 獲取返回結果的 json
var jsonData = pm.response.json();
// 測試 2 - 返回的 json 中必須有 access_token 欄位
pm.expect(jsonData).to.have.property('access_token');
// 設置全局變數 jmixToken
pm.globals.set("jmixToken", jsonData.access_token);
})
這裡我們還可以做一點優化,那就是針對上面代碼中的 “測試 1”,我們檢查了 HTTP 的返回狀態碼為 200,其實針對所有的請求,我們可能都需要做這個檢查,那麼如果不複製粘貼代碼,有沒有簡化的方法呢?
有的,Postman 提供了集合級別的測試腳本,定義在集合中的測試腳本,會對每個 API 都適用。比如,我們可以把驗證 HTTP 狀態碼的測試放到集合中:
小結
到這裡,我們開發階段對於請求的優化就結束了,通過使用變數,可以優化 API 中的數據,將相同的數據都定義在變數中。通過測試腳本,我們可以對 API 進行測試,也可以更新各種變數,避免手動修改的麻煩。我們的示例中演示的更新 token 是最常見的腳本功能,除此之外,比方說我們要測試的發帖和回帖功能,可以在發帖後將帖子的 ID 保存在變數中,測試回帖功能時,直接使用變數存儲的帖子 ID,這些具體的業務場景,可以根據項目靈活變化。
測試階段
開發完成後,我們就需要將 API 部署至測試或者 Stage 環境,交給測試人員或者前端開發人員進行試集成了。那麼在這個階段,你或許想在測試人員工作前自己先測試一遍,或者如果測試有問題,而你作為後臺開發人員,也難免需要直接調用測試環境的 API 觀察輸出結果。這就有了一個新的問題:我們在之前的介面定義都是 http://localhost:8080
開頭的地址,怎麼能方便地切換到測試地址呢?
答案還是用變數。但是這一次,我們使用的是環境變數集合。
例如,我們可以創建兩套環境變數,分別為 env_dev
和 env_prod
,其中都定義了變數 jmixAppUrl
,在 env_dev
中,該變數的值為 http://localhost:8080
,而在 env_prod
中,該變數的值為 https://your.test.env.ip:test_port
,然後修改每個請求,將原本的 http://localhost:8080
地址換成變數 {{jmixAppUrl}}
:
使用時,通過右上角的環境變數集合切換功能,就可以切換不同的環境了。
發佈文檔
如果你的測試或者前端也使用 Postman,那麼可能導出 API 集合文件再交由同事導入,可能是比較方便的方法。但其實 Postman 在文檔發佈這個功能上,也做了不少工作。
右鍵點擊集合,有一個 View documentation
菜單,或者通過下圖的按鈕也可以查看集合的文檔
在查看文檔時,右上角有一個 Publish
按鈕,可以將你的文檔公開發佈,並提供一個 URL 地址用於訪問。這樣的話,其他同事如果不使用 Postman,只需要訪問該地址,就可以看到 API 的文檔。
在發佈時,可以選擇環境變數集合,這樣會用集合內的變數值直接替換 API 中的所有變數,這樣一來,看文檔的人不會讀到看不懂的變數。下圖是一個發佈的文檔示例,前端用戶還可以根據編程語言,選擇對應的代碼樣例:
發佈後的文檔會實時更新,也就是說,任何你在 Postman 中對集合 API 的修改都會實時同步至文檔中。比如新增或刪除某個 API、修改 API 請求體等等。
項目級別優化
其實,我們最後還做了一個項目級別的優化,這個案例可能不具有通用性,但是也可以給大家一個思路:
公共 API 抽離
由於我們的項目後臺都是基於 Jmix/CUBA 框架開發的,因此,我們做瞭如下改動:
- 新建 Postman 集合 - Jmix/CUBA 通用介面,其中包含了 Jmix 和 CUBA 各自獲取本地 token 的 API,以及從我們 SSO IDP 獲取 token 的 API。
- 新建全局變數存儲 token,全局變數有
jmixToken
,cubaToken
,ssoToken
。並且在上述三個介面的測試腳本中,分別更新這三個全局變數。
這樣做的好處是,不需要在每個項目中單獨提供獲取 token 的 API,並能保證獲取的 token 全局可用。
統一添加 Authorization 請求頭
在業務 API 集合中,我們為 Collection 添加了 Pre-request Script
,這個腳本會在集合內的每個請求發出前先執行。我們就是用這個腳本為請求添加請求頭,代碼很簡單,例如,對於使用 ssoToken
和 jmixToken
的 Jmix 項目,我們是這樣做的:
因此,對於集合內的每個請求,不需要單獨設置 Authorization 請求頭了。
統一業務 API 返回結構
最後,我們在代碼層面對每個業務 API 的返回結構做了統一,都使用這樣的返回結構:
public class RestResult<T extends Serializable> implements Serializable {
/**
* 業務狀態碼
*/
private int businessCode;
/**
* 提示信息
*/
private String msg;
/**
* 數據
*/
private T data;
//...
}
我們為所有的成功返回都定義了同一個 businessCode
,這樣的話,在 Postman 的 Tests 腳本中,可以添加代碼直接檢查業務層面的返回結果是否成功,例如,我們定義 10000 為業務結果正確的返回值:
pm.test("Success return", function () {
pm.response.to.have.status(200);
pm.expect(pm.response.json().businessCode).to.eql(10000);
})
結語
本文介紹了一些使用免費 Postman 的進階技巧:變數、腳本、文檔發佈。而現在 Postman 也在往 SaaS 方向發展,推出了團隊協作功能,像文檔發佈、API 導出導入這些功能在團隊模式下用不到了,因為 API 集合可以協作完成,文檔也可以團隊內共用。Postman 作為一款 API 平臺,確實能在一定程度上提升團隊的開發效率和協作。