一、當我們在說前後端協作的時候,我們在說什麼
目前前後端分離已成為主流,前後端開發環境互相獨立的情況下,如何提高前後端協作效率已然成為每個公司不得不考慮的問題。
以一個專案開發週期為例,在協作上一般需要面對以下幾個問題:
- 專案開發初期,前後端需要就介面定義達成一致並且最好能在一個地方持久化,並且隨著專案迭代開發持續維護
- 前後端在並行開發時前端需要先對介面資料進行 mock
- 專案聯調前,對於前端同學來說,我們需要能科學的判斷後端同學的介面是否真的達到可聯調狀態了
二、有贊之前是怎麼做的
1. 對於介面定義
我相信很多公司跟有贊一樣,沒有專門的API文件站點,也沒有相應的工具,基本在一個通用的文件站點由工程師自己手動建立、維護介面文件。
有贊也同樣使用這種方式去維護介面文件,但這種方式會帶來一些比較明顯的問題:
- 建立、維護成本大,在後端同學比較忙的情況下,不見得可以及時提供、更新文件。
- 手動編寫容易出錯。
- 由於是通用的文件站點,介面文件展示並不是非常直觀。
這些問題都會增加協作雙方的溝通成本,進而影響專案整體進度。
2. 對於資料 mock
前端同學對於介面資料 mock 應該是非常熟悉的,而且每個公司或多或少都會有自己的一些套路跟方案。
比如最開始,大家可能會使用在前端程式碼裡面直接寫死 mock 資料的方式。你可能會對下面這段程式碼比較熟悉:
import mockData from './mockdata.js'
// ajax(url).then(dosomething)
// 資料 mock
setTimeout(mockData => {
dosomething(mockData);
}, 1000);
複製程式碼
通過這種方式,前端同學可以在開發階段手動 mock 後端介面資料,從而實現並行開發。
但這種方式的缺點顯而易見:
- setTimeout 顯然是無法完全模擬 ajax 的行為的。
- 上線前需要修改程式碼,重新打包。
- 因為有缺點2,會引入額外的風險點。(忘記修改重新打包)
- 是否要保留 mock 資料和相應的邏輯以便之後專案迭代。
- 如果後端介面變更,無法及時響應(依賴於前後埠頭通知)
因為這些缺點和 nodejs 的崛起,前端同學自然會想到使用 node 做一套 mock 伺服器。於是就有了下面這種方式:
// ajax(realUrl).then(dosomething)
ajax(mockUrl).then(dosomething)
複製程式碼
這種方式解決了使用 setTimeout 模擬真實請求的問題並且極大的減少了 mock 功能對業務的侵入。而且因為 mock 資料在遠端,前後端可同時修改,減少溝通成本。
但是這種方式還是無法解決問題 2
、3
、4
。
有贊就曾使用過這種方式的變體,我們依賴特定 ajax
庫的全域性鉤子,解決了問題 2
、3
、4
。但卻也帶來了其他問題,比如對特定 ajax
庫的強依賴。
3. 聯調狀態判斷
我相信很多公司跟有贊一樣,聯調時間是在專案開始的時候開發預估的,開始聯調的時候前端其實並不知道後端介面是否真的OK了,或者說至少能調通了。所以常常會碰到的問題是,後端同學告訴你可以聯調後,你發現介面報的全是 404
或者 500
,最後一查是後端環境配置有問題。
其實有贊在之前也並沒有找到一個比較好的方案,到現在也只能說還處於探索階段。
三、那麼到底什麼樣的協作方式是我們想要的
1. 對於文件來說
- 後端同學能快速生成文件,並且持續維護。
- 文件需要包含足夠多的資訊
- 友好的介面定義展示
2. 對於資料 mock
- 方便合作雙方可同時修改,即時生效
- 最好可以自動生成隨機返回值
- 能根據不同的請求引數返回不同資料
- 修改 mock 資料的行為,可以快速通知到合作方,避免雙方對資料格式認知不同步
3. 對於更好的判斷聯調時間
通過比較科學的方式判斷後端介面是否已經可被呼叫。
四、ZanApi 是如何做到的
首先,後端同學在寫文件這件事上,成本是否可以為零?
有贊目前在大力推進服務化,並且引入了 node
作為中間層。所以在有贊,前後端的邊界變成了 browser + node
-> java 服務化介面
。
對於 java 同學來說,業界已經一些比較成熟的方案來生成介面文件,比如 swagger
、api blueprint
、swift
。
但這些方案要麼需要 java 同學引入很多非專案的三方依賴,要麼有它自己的一套介面定義方式從而增加 java 同學的工作量。
而且有些方案並不適用於目前越來越主流的 browser & node
-> 協議閘道器
-> java 服務化介面
這種前後端協作方式。
1. ZanApi 的文件生成方案

解決快速生成、更新文件的問題
為了讓 java 同學更方便的生成文件,我們為 java 同學提供了IDEA Intellij 外掛
。
最終的效果是,java 同學能夠一鍵生成、更新介面文件。

解決文件資料問題及展示
我們在遠端部署了一個 java 解析伺服器
,通過該解析服務,我們可以將 java
程式碼裡的備註抽取出來生成介面欄位註釋。最終一個介面的返回值定義可能是這樣的。

所以,如果 java 同學本身有比較好的寫註釋的習慣,那麼對他來說生成一個合格的介面文件將是零成本的。
2. ZanApi的資料 mock 方案
目前有贊完整的資料 mock 方案如圖所示:

從客戶端(pc / mobile)發起的請求在經過 ZanProxy
過濾後,將需要 mock 的介面打到 ZanApi
上,經過 ZanApi
返回 mock 資料。
解決可同時修改,快速通知的問題
由於 ZanApi 部署在遠端,前後端可同時修改,所以本身天然沒有這個問題。
並且在 ZanApi 系統上,你可以收到自己收藏的介面的 mock 資料變更通知,可以較快的感知 mock 資料的變更。

支援多份 mock 資料,自動匹配
ZanApi 支援為同一個介面新增多份 mock 資料,請求在資料 mock 時,ZanApi 能通過請求引數,自動返回不同 mock 資料。
支援根據介面定義返回隨機資料
當 java 同學通過 Idea 外掛
自動生成介面文件時,ZanApi 會通過解析服務獲取介面的返回值定義並自動講定義轉化成 JSONSchema
格式。
當需要返回隨機資料時,ZanApi 可以根據介面返回值的 JSONSchema
定義產生隨機數進而返回給客戶端。
3. ZanApi 對聯調的支援
在 ZanApi 上,你可以為每個介面建立不同環境下的測試用例
。在測試用例
的基礎上,你可以以專案維度建立一個介面集合
。
當介面集合
建立完畢後,ZanApi 提供了 一鍵測試 功能。
一鍵測試功能會獲取該介面集合
內所有的介面,並將這些介面中定義的測試用例
完整的跑一遍。如果其中某一個介面無法調通,那麼 ZanApi 將提示你該介面測試失敗。
甚至,ZanApi 允許你通過對比真實介面返回值和介面返回值定義(或者對比之前已存在的某個 mock 資料)來判斷該介面是否符合預期。
比如,在介面的返回值定義中欄位 count
是一個數字,但是 ZanApi 發現測試用例返回的真實資料中該欄位是一個 string
,那麼該測試用例也將不會通過。
UI如下:

五、最後
在有贊技術開放日上介紹了 ZanApi 後發現大家對 ZanApi 還是有著比較大的興趣。但是由於我們尚未有時間整理開源相關的事宜,並且確實 ZanApi 還有很多不成熟的地方啊,所以 ZanApi 開源在短期內應該沒辦法實現。
但我們一直有開源的計劃,併為之努力著
