大家好,我是零一,想問一下你們,作為前端,最痛苦的是什麼時候?
每個迭代,需求文檔跟設計稿都出來了,靜態頁面唰唰兩天就做完了。可是做前端又不是簡單地把後端吐出來的數據放到頁面上就完了,還有各種前端處理邏輯啊。
後端接口還沒出來,我就得邊寫代碼邊測前端效果,又沒有真實數據。有人建議用 Mock 工具,可是每個接口都要自己寫 Mock 規則,這得浪費多少時間呀。
等到後端好不容易把接口寫出來了,一對接聯調,好多字段的數據又跟我 Mock 的數據對不上,又得重新改代碼。

每個迭代都是一場折磨。
就是那種,明明知道這個地方整個團隊都可以更有效率,但偏偏就是做不到的無力感。
黎明的希望直到有一天,我遇到這個神器。我的效率提升了 100%。
我可以用最省力最優雅的方式得到我需要的 Mock 數據,甚至不需要任何配置。而且,聯調時候曾經遇到的各種令人崩潰的前後端數據對接問題,統統不!見!了!
就是這個⬇️

我研究了整整一周,越研究越是心驚。這個工具太強大,完全超出我的預期,就如《倚天屠龍記》里張無忌修煉的乾坤大挪移,練完一層,上面還有一層,每一層都是一片全新的天地。
我曾經以為,定接口什麼的你們後端定就行了,跟我前端有什麼關係。定好了吐數據給我就行了。
我曾經以為,寫接口文檔什麼的完全是浪費時間,邊寫代碼邊改接口不好嘛。
直到我遇到這個神器,我才明白好的工作習慣能給我提升多少效率。
現在的我已經不一樣了。我認為這款神器能夠把全中國前端程序員的工作效率都提升一倍。我也希望在讀這篇文章的你,能夠好好把這款工具用起來。
以下還有 3000 字,閱讀時長 5~10 分鐘。如果你嫌讀文字太麻煩,這裡也有個視頻,內容是一樣的。
好,接下來我要發功了。

Apifox 是個 API 協作工具,用它來做 Mock 數據的基礎也是 API 文檔。在 Apifox 里維護的 API 可以生成好看的在線接口文檔,也可以像 Postman 那樣一鍵調試,像 JMeter 那樣做測試,還可以直接 Mock 數據。不過今天我們只聊 Mock。
首先,你需要在 Apifox 裡面創建一個接口,定義好請求參數和返回數據結構。
好了,保存。完成!
……………………
等會兒?Mock 呢?怎麼就完成了?Mock 規則在哪兒寫?

真的就完成了。
Apifox 會自動啟動一個本地的 Mock 服務,我複製一下 Apifox 自動生成的 Mock 地址,用瀏覽器打開看下效果。

就是這麼簡單!就是這麼方便!
什麼!都不需要!配置!

其實我們遇到的大部分 API 返回數據都是通用的,用戶名、手機號、地址、郵箱、時間戳,等等等等。但是你要去寫 Mock 規則就很麻煩。你要怎麼生成一個看起來合理的中國人名?
在 Apifox 裡面,這變成了最簡單的事情,甚至是完全無感的。只要寫 API 文檔的時候把返回的數據結構定義好,這個事情就完成了。Apifox 會根據字段名稱智能生成 Mock 數據,不需要任何配置。
如接口返回的數據結構里某個字段名稱叫username就會得到「程敏」「王寧」「安慕希」「李瑪璧」。
字段名稱叫phone,就會得到15237829132、18907284633。
字段名稱叫city,就會得到杭州市、高雄市、博爾塔拉蒙古自治州。
甚至如果你的字段名稱叫icon,就會返回一個圖片 URL,打開就真的是一張 png 圖片!
如果你們團隊使用的是 Swagger 等其他工具管理 API 文檔,也可以導入到 Apifox(Apifox 支持 20 多種格式數據導入,還可以設置定時自動導入),一樣可以使用這個智能 Mock,一樣是零配置自動生成所有 Mock 數據。
完全不用操心任何 Mock 數據配置的問題,只要接口定好了,Mock 數據就有了,我什麼前端代碼都能寫。

有的同學問,你這個都是預設死的吧?我怎麼知道寫什麼參數名稱你會給我 Mock 出什麼數據來?好,這就是 Apifox Mock 功能的第二層:自定義智能 Mock 規則。
在 Apifox 裡面內置了一整套 Mock 規則,當我們的返回字段名匹配上了其中的某條規則,就會根據對應規則生成隨機值(Mock.js 語法規則)。

字段名稱的匹配方式支持通配符和正則表達式,比如字段只要以 「url」 結尾,就會得到一個正確的網址;以 「mail」 打頭,就會得到一個郵箱地址。
要是以 「time」 結尾,那還會自動根據字段的數據類型來 Mock 值:string 類型的話就返回一個 'yyyy-mm-dd hh:mm:ss' 格式時間;integer 類型的話就返回一個時間戳。是不是很智能?!
有內置規則,當然就可以自定義新規則。
比如我們公司的訂單 id 是以 「DD」 打頭的十位數字,我就可以新建一個 string 類型的規則,匹配規則寫 「*orderid」 , mock 規則寫一個正則表達式:@regexp(/DD\d{10}/)。這樣,只要我任何一個接口返回字段是以 「orderid」 結尾,都會得到一個 「DD1284918414」 這樣的返回值。

有的同學說,你這個是比較通用的數據類型,可我還有很多沒那麼通用的類型,比如寵物店上架的寵物,有三種狀態:可售、已售、待上架,要怎麼 Mock 出來?
在 Apifox 裡面,定義接口返回數據結構的時候每個字段都有一個「高級設置」的概念。比如我寵物的上架狀態還可以定義為枚舉,枚舉可選值為(「available」,「sold」,「pending」)。如果接口這樣定義了,那麼 Mock 就會自動從這三個字符串里取值。

這個字段高級設置里不止有枚舉,還可以設置長度範圍、正則規則等。如果字段類型是數字,還可以設置最大值最小值等。
如果你對 JSON Schema 比較熟的話,也可以直接寫 Schema,那可定義空間就更大了。
而且我們要注意:這個時候我們設的其實不是 Mock 規則,而是接口返回值的數據結構定義,這個是會對接口調試的自動校驗功能生效的,如果後端接口返回的數據不符合這裡的設置,Apifox 會返回一個「數據結構校驗失敗」,就告訴後端你接口返回數據結構不對。
而我們的 Mock 數據也是根據這裡的設置自動生成,不需要任何額外配置。

爽不爽,可以直接甩一張截圖去懟後端了。

有的同學說,那我還有一種場景,比如我這個用戶名字段,數據定義里其實是允許他輸入任意字符串的,可是我 Mock 是需要一個真實姓名的,不能靠字段定義啊。
而且,你剛才演示的都是中國人名,我的客戶都是歐美人怎麼辦。
啊,終於要針對特定接口設置一點點規則了。

在 Apifox 里,給接口定義數據結構的時候是可以給每個字段設置 Mock 規則的,而且直接就可以選一系列的常用 Mock 規則,常見的各種數據類型其實都齊全了。比如我需要一個外文人名,我就可以在這裡寫 @name,運行一下就會得到 「Larry Smith」 「Susan Lee」 這樣的英文名。
如果前面說的智能 Mock 滿足不了你,在這裡設置規則就可以覆蓋掉內置規則。這裡支持 Mock.js 和正則表達式,只要你能想到的規則,全都 Mock 得出來。

而且 Apifox 支持 數據模型(Schema) 定義,不同的接口可以復用相同的數據模型,模型里定義的規則在所有引用它的接口裡都會生效,不需要任何額外的配置。
一次 Mock,終身享受。

還有那麼一些同學,他們說,希望能讓我自己定義:根據不同的參數值,返回不同的數據。
比如我請求的參數寵物ID 為 1 就返回一個在售的寵物數據,如果寵物ID 為 2 就返回一個已售的寵物數據。我前端可以把幾種狀態的頁面都做出來。
好吧,Apifox mock 的第五層就是為你準備的。
在 Apifox 的「接口管理」 有一個 「高級 Mock」 標籤頁。在這裡我們可以添加「期望」。

一個期望就是指當你的請求包含某個參數值的時候,就返回特定的數據。
比如我設定我的1號寵物是在售的,2號寵物是已售出的,3號寵物是記錄不存在的,DDD 號寵物是「 ID 格式不正確」的。我把這些返回值都設好。
之後,我發送的請求參數是1的時候,就返回一個在售的寵物信息;2返回一個已售的;3返回一個「404 not found」,4返回一個「Invalid Param」。
啊,簡直能模擬出來一個後端服務器了!

你覺得這個 Mock 功能已經非常強大了是吧。我最開頭提了張無忌,你知道張無忌的乾坤大挪移總共有幾層嗎?

我們進入高級 Mock 寫期望的時候,鼠標放在這個支持 「Mock.js 語法」上會浮出來一段示例。

這個示例是講什麼的呢?我們可以在 Apifox 裡面實際運行一下試試。

它生成了一個 JSON 格式的數組!
總共有 20 組 id 和名字,比如你在前端要生成一個填滿數據的二維表格,一次就能 Mock 一整套!只需要短短几行代碼!
我們回來看這個語法示例,正常的 JSON 裡面插入了大括號百分號包裹的兩段 「for」 代碼,它就是 JS 模板語法(Nunjucks語法),可以使用它來生成複雜的數據結構!
不但支持 for 循環!還支持 if 分支!還支持正則表達式!還支持調用函數!
你說!是不是有我(加上 Apifox)就夠了!還要後端做什麼!

還有???
這是最新的 Apifox 2.1.7 才有的強大功能。
新版本的高級 Mock 增加了一個「腳本」的 Tab,這個高級 Mock 自定義腳本是做什麼用的呢?

我們來考慮一個實際的案例。我有一個「查詢寵物列表」的 GET 接口,它的請求參數是 page 和 pageSize,取值是 6 和 10,含義就是我要查寵物列表的第 6 頁,每頁限定 10 條記錄。這是個很常見的翻頁場景。

返回數據首先是一個數組,每一條是我查出來的這一頁的一個寵物。下面還有一個 page 和 total,也就是當前頁碼和總計多少條記錄。請求一下,返回的 Mock 數據就是一系列的寵物信息。
到下面的 page 字段,出現問題了:我請求的明明請求的是第 6 頁的數據,你給我返回 page 是第 10 頁算什麼意思。

再翻翻頁,新的問題又出現了:剛才還是總共 25 頁呢,我一翻頁就變成總共 40 頁了???而且第 10 頁的下一頁是 22 頁?

我希望 Mock 出來的數據是什麼樣的呢?應該是我請求的是第幾頁,返回來的數據就是第幾頁;然後總頁數應該是固定的,不會因為我翻前翻後就變。
這時候我們就需要高級 Mock 的自定義腳本了。
在自定義腳本界面的右側有一段示例代碼,我們仔細讀一下。

這樣,我請求的是第幾頁,返回的就也是對應的第幾頁,然後總頁數是保持 12 不變(120 除以每頁 10 個)。

這個自定義腳本就可以做很多事情了,比如我需要根據用戶的性別是男是女 Mock 出返回的不同頭像;或者先 Mock 出出生日期,然後用出生日期拼裝成對應的身份證號等等,可以讓我們 Mock 出來的數據彼此吻合。
自定義腳本可以操作的對象就是這個 fox.mockRequest 和 fox.mockResponse,可以獲取請求參數、Header、Cookie,修改響應 Body、HTTP 狀態碼等,甚至響應的延時都可以自定義。
你就說牛不牛吧!

Apifox Mock 功能的七層天梯,打完收功。
如果你是個前端,並且讀到了這裡,我覺得你應該鼓一下掌。
Apifox 的 Mock 功能完全值得你點一下閱讀原文然後去下載。其他的 API 和 Mock 工具你全都可以扔掉了。
記得要下載Apifox桌面版使用,WEB 版目前還不支持 Mock 功能。
最後提醒一下,Mock 只是 Apifox 的功能中的一小部分。Apifox = Postman + Swagger + Mock + Jmeter,它的功能遠不止這篇文章里的這些。
