摘要:前端開發如何做好本地接口模擬之前有寫過一篇本地化接口模擬前后端并行開發,講到過本地接口模擬,但不太細致。有哪些途徑本地接口模擬一般分為工具層面和代碼層面。因為本地接口模擬功能主要是針對的返回值為格式的異步請求,所以這種方式主要用文件。
前端開發如何做好本地接口模擬
之前有寫過一篇 本地化接口模擬、前后端并行開發,講到過本地接口模擬,但不太細致。這次細細的說說本地接口模擬。
1. 有什么好處本地接口模擬最大的好處就是能夠使前后端項目解耦,前端更專注于開發,減少線上調試,以此提升開發效率。
2. 有哪些途徑本地接口模擬一般分為工具層面和代碼層面。
3. 工具層面就工具層面而言,一般是由項目的構建工具提供的功能。比如,當我們用 webpack-dev-server、webpack-dev-middleware + browser-sync 等工具時,就可以向工具里添加本地接口模擬功能。
注:這里不講解工具如 webpack-dev-server、webpack-dev-middleware + browser-sync 等的用法,如有需要,可以自己去了解一下
下面以 webpack-dev-server 為例進行講解,其他工具類似。
3.1 靜態文件最簡單的,我們可以用靜態 json 文件做本地接口模擬功能。
|-- / # 項目根目錄 |-- mock/ # 模擬數據目錄(可以自定義) |-- 1.json |-- 2.json |-- ... |-- ... # 其他文件
然后用 webpack-dev-server 以項目根目錄為基地址來開啟本地開發調試,在頁面中就可以這樣訪問:
fetch("/mock/1.json"); // 訪問 1.json fetch("/mock/2.json"); // 訪問 2.json # 可以將 fetch 換成其他請求方式
這種方式可以訪問項目中所有的文件,不光是 json 文件,其他的如 html、js、css 之類的文本文件、如圖片之類的二進制文件也可以訪問。另外,只要文件有更新,刷新瀏覽器頁面就可以重新獲取新的文件,沒有緩存。
因為本地接口模擬功能主要是針對的返回值為 json 格式的異步請求,所以這種方式主要用 json 文件。
這種方式是最簡單、快捷、使用難度最低的方式。
3.2 動態注冊接口使用靜態文件做本地接口模擬功能主要存在以下的一些問題:
靜態文件只能以 get 方法訪問
輸入數據是靜態的,不能做運算、循環、判斷等,也不能根據請求參數做出不同的響應
本地接口名與服務器上的接口名不一樣,這就比較麻煩了,每次上線到服務器的時候都得改接口名
所以,多數情況下,都會采用動態注冊接口的方式做本地接口模擬功能。
這種方式是用 js 文件編寫一系列的 路由 => 響應 映射,然后動態的把定義好的接口注冊到工具實例中。
目錄結構:
|-- / # 項目根目錄 |-- mock/ # 模擬數據目錄(可以自定義) |-- user.js |-- home.js |-- ... |-- ... # 其他文件
示例 mock 文件的寫法(可以自定規范,下面只是演示):
# mock/user.js module.exports = { "GET /user/profile": { ... }, // 直接返回一個對象 "POST /user/update": (req, res) => { ... }, // 根據 `req, res` 的自定義響應 ... }; # mock/home.js const mockjs = require("mockjs"); module.exports = { "GET /home/list": mockjs.mock({ // 用 mockjs 輔助生成假數據 "list|1-10": [{ "id|+1": 1 }], }), };
注:
上面的寫法只是示例,可以自定規范、書寫格式等
可以用 mockjs 庫來幫助生成假數據
webpack-dev-server 的相關配置:
# webpack.config.js const beforeDevServer = app => { // 在這里讀取 mock 目錄下的所有文件,按照一定的規范和格式,載入動態接口 // 比如: app.get("/user/profile", function(req, res) { res.json({ ... }); // 返回文件中定義的 `GET /user/profile` 的值 }); app.post("/user/update", function(req, res) { handle(req, res); // handle:文件中定義的 `POST /user/update` 的自定義處理函數 }); ... }; module.exports = { //... devServer: { before: beforeDevServer, } };
然后用 webpack-dev-server 開啟本地開發調試,在頁面中就可以這樣訪問:
fetch("/user/profile"); // 訪問 /user/profile fetch("/user/update", {method: "post", body: { ... }}); // 訪問 /user/update fetch("/home/list"); // 訪問 /home/list # 可以將 fetch 換成其他請求方式
一般來說,我們還會用上 chokidar 來監聽 mock 目錄下的文件變動,來更新路由及其響應,以此能夠做到每次訪問到的都是最新的資源(因為 node 針對某個模塊只會加載一次)。
const chokidar = require("chokidar"); const watcher = chokidar.watch("./mock"); watcher.on("change", path => { // 先清除模塊緩存,保證加載最新的資源 if (require.cache[path]) delete require.cache[path]; const mapObj = require(path); // 接下來把映射對象 mapObj 重新映射到 app 中 ... });
這種方式比較復雜,尤其是對項目搭建者要求比較高,需要對相關工具有深入的了解,好在社區已經有封裝好的工具:roadhog。
但這種方式對使用者是很棒的,因為能夠完全模擬服務器接口,包括接口名、HTTP 方法、參數、返回值等,所以同樣的代碼既可以在本地運行,也可以在服務器上運行。
所以,這也是比較推薦的方式。
注:上面的代碼只是演示構建過程,并不保證可以運行3.3 使用代理
這種方式是把本地模擬文件寫在另一個多帶帶項目里,然后使用使用代理的方式,訪問模擬接口。
mock 項目(以 koa 為例):
const Koa = require("koa"); const Router = require("koa-router"); const app = new Koa(); const router = new Router(); router.get("/api/user/profile", (ctx, next) => { ctx.body = { ... }; }); router.post("/api/user/update", (ctx, next) => { // ... }); app .use(router.routes()) .use(router.allowedMethods()); app.listen(3000);
app 應用項目:
webpack-dev-server 的相關配置:
# webpack.config.js module.exports = { //... devServer: { proxy: { "/api": "http://localhost:3000" // 把所有 `/api` 開頭的接口都代理到 `mock` 項目中 } } };
然后用 webpack-dev-server 開啟本地開發調試,在頁面中就可以這樣訪問:
fetch("/api/user/profile"); // 訪問 mock 項目的 /api/user/profile fetch("/api/user/update", {method: "post", body: { ... }}); // 訪問 mock 項目的 /api/user/update # 可以將 fetch 換成其他請求方式
一般來說,我們還會用上 nodemon 來監聽 mock 項目中的文件變動,自動重啟 mock 應用程序,以此能夠做到每次訪問到的都是最新的資源(因為 node 針對某個模塊只會加載一次)。
nodemon app.js
這種方式可以統一管理多個項目的數據模擬文件,多個項目可以共享一些模擬數據。
3.4 線上接口模擬有些時候,當我們在產品環境的時候(在線上)也可能想用模擬數據(比如APP、微信小程序、用于演示的 web 應用等),或者需要一個線上的地方來統一管理模擬數據時,就需要線上接口模擬了。
線上接口模擬擁有完備的 UI 操作界面,可以添加多個用戶、多個團隊、多個倉庫,可以生成為每一個請求參數添加類型限定、描述,為響應數據字段添加描述等。
因為是在線上的模擬數據,所以在任何地方都可用,不管是本地開發,還是線上調試、演示,都是可用的。
比較有名的線上接口模擬工具有:
easy-mock:線上演示地址 https://easy-mock.com/
RAP / rap2-delos + rap2-dolores:阿里出品,線上演示地址 http://rap2.taobao.org/
3.4.1 easy-mock環境需求:Node.js (>= v8.9) & MongoDB (>= v3.4) & Redis(>= v4.0)
安裝步驟請參考官方的文檔 easy-mock#quick-start
easy-mock 主要提供了以下的一些功能:
支持接口代理
支持快捷鍵操作
支持協同編輯
支持團隊項目
支持 RESTful
支持 Swagger | OpenAPI Specification (1.2 & 2.0 & 3.0)
基于 Swagger 快速創建項目
支持顯示接口入參與返回值
支持顯示實體類
支持靈活性與擴展性更高的響應式數據開發
支持自定義響應配置(例:status/headers/cookies)
支持 Mock.js 語法
支持 restc 方式的接口預覽
3.4.2 RAP / rap2-delos + rap2-dolores環境需求:Node.js (>= v8.9) & MySQL (>= v5.7) & Redis(>= v4.0)
RAP 目前有兩個版本,第一個版本的 RAP 已經被官方廢棄了,建議用第二個版本。
RAP2 分成了兩個包:
rap2-delos:后端數據 API 服務器
rap2-dolores:前端靜態資源
RAP2 的安裝步驟要麻煩一些,rap2-delos 可以參考官方文檔 rap2-delos#部署、非官方rap2-delos部署文檔,rap2-dolores 可以參考官方文檔 rap2-dolores#deployment-部署。
RAP2 提供了與 easy-mock 類似的功能,但比 easy-mock 要更強大一些,當然也要復雜一些,比如:
對請求參數支持更完備,比如 headers、query params、body params
對響應數據支持更完備,比如可以為每個字段添加描述、限定類型等
3.4.3 兩者之間比較RAP2 比 easy-mock 要更強大一些,但也要復雜一些,所以追求功能完備的可以用 RAP2,追求簡單快捷的可以用 easy-mock。
4. 代碼層面從上面可以看出,除了第二種方式 動態注冊接口 之外,其他的方式都不能做到完全模擬服務器環境,至少服務器接口地址與本地模擬地址不一樣,這就有一個問題:每次上線前都得改成服務器地址。
另外,前端與后端對接的過程中也總是難免會遇到一些問題:
前端傳的參數與后端所需的參數難以保持一致:比如分頁,前端定的 page、從 1 開始,后端定的 pageNum、從 0 開始
前端需要的數據與后端返回的數據相差很大,需要對返回的數據做處理
后端可能更改字段名或者數據類型,導致前端要查找、并更新相應的代碼
一種好的、解決這些問題的方式是對應用進行分層、把異步請求進行隔離封裝。
我一般會用 see-fetch、see-ajax 對異步請求進行隔離封裝。
注:see-fetch 是對 window.fetch 的封裝,see-ajax 是對 XMLHttpRequest 對象的封裝。
4.1 以 see-fetch 為例進行說明:可以在代碼中設置多個內部環境,然后針對不同的外部環境設置不同的內部環境(如:本地環境、線上環境等),這樣就可以做到不改代碼,只改一個環境值。
如果搭配 define-plugin,連環境值都不需要改,直接由 define-plugin 在運行的過程中指定。
import seeFetch from "see-fetch"; seeFetch.setEnv(0/1/2/3); seeFetch.setEnv(__SEE_ENV__); // __SEE_ENV__ 由 define-plugin 運行中指定
配置一個異步請求:
seeFetch.config(name, { // 定義一個名為 name 的異步請求(下面的配置可以是多環境,每個環境可以設置不同的值) method, // 當前請求使用什么 http 方法 stringify, settings, url, // 當前請求 url 地址 req, // 請求參數鍵名的映射,比如 `page => pageNum` pre, // 操作請求參數,比如 page 從 1 開始改成從 0 開始 refactor, // 重構響應數據,如字段重命名、類型轉換等 post, // 操作響應數據,以把數據轉換成自己所需要的數據 implement, // 自定義請求,比如后端返回一個模板字符串,而不是接口 });
發起訪問:
seeFetch(name, params).then(result => { // 這里的 result 是經過格式化后的最終數據 });
從上面可以看出:一個請求的不確定性都被封裝到了配置中,不管是接口地址更新、前端請求參數與后端不一致、后端響應數據與前端所需的差異很大等,都可以在配置中進行操作,而絲毫不需要改其他地方的代碼。
這樣,如果后端接口有什么改動的,只需要找到配置文件進行更新,而不用在項目中找哪里使用了這個接口。
如此,既能很好的使用本地數據模擬,也可以從容應對后端接口的改動,便能事半功倍。
后續更多博客,查看 https://github.com/senntyou/blogs
作者:深予之 (@senntyou)
版權聲明:自由轉載-非商用-非衍生-保持署名(創意共享3.0許可證)
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/100739.html
摘要:移動端應用一般都運行在微信瀏覽器中中手機瀏覽器中。因為微信瀏覽器是定制的瀏覽器,一般的遠程調試方式都不可用,需要配合特定的工具,如微信開發者工具。 前端如何高效的與后端協作開發 1. 前后端分離 前端與后端的分離,能使前端的開發脫離后端的開發模式,擁有更大的自由度,以此便可做前端工程化、組件化、單頁面應用等。 可以參考:前后端分離、web與static服務器分離 2. 盡量避免后端模板...
摘要:移動端應用一般都運行在微信瀏覽器中中手機瀏覽器中。因為微信瀏覽器是定制的瀏覽器,一般的遠程調試方式都不可用,需要配合特定的工具,如微信開發者工具。 前端如何高效的與后端協作開發 1. 前后端分離 前端與后端的分離,能使前端的開發脫離后端的開發模式,擁有更大的自由度,以此便可做前端工程化、組件化、單頁面應用等。 可以參考:前后端分離、web與static服務器分離 2. 盡量避免后端模板...
摘要:實現前后端分離的心得對目前的來說,前后端分離已經變得越來越流行了,越來越多的企業網站都開始往這個方向靠攏。前后端工作分配不均。 實現前后端分離的心得 對目前的web來說,前后端分離已經變得越來越流行了,越來越多的企業/網站都開始往這個方向靠攏。那么,為什么要選擇前后端分離呢?前后端分離對實際開發有什么好處呢? 為什么選擇前后端分離 在以前傳統的網站開發中,前端一般扮演的只是切圖的工作...
摘要:本文由云社區發表絕大多數程序只考慮了接口正常工作的場景,而用戶在使用我們的產品時遇到的各類異常,全都丟在看似的中。在面板,還可以對請求進行暫停延遲等網絡異常的模擬。小程序實現最后,留一道思考題。 本文由云+社區發表 絕大多數程序只考慮了接口正常工作的場景,而用戶在使用我們的產品時遇到的各類異常,全都丟在看似 ok 的 try catch 中。如果沒有做好異常的兼容和兜底處理,會極大的影...
摘要:如何構建大型的前端項目搭建好項目的腳手架一般新開發一個項目時,我們會首先搭建好一個腳手架,然后才會開始寫代碼。組件化一般分為項目內的組件化和項目外的組件化。 如何構建大型的前端項目 1. 搭建好項目的腳手架 一般新開發一個項目時,我們會首先搭建好一個腳手架,然后才會開始寫代碼。一般腳手架都應當有以下的幾個功能: 自動化構建代碼,比如打包、壓縮、上傳等功能 本地開發與調試,并有熱替換與...
閱讀 902·2021-11-22 13:53
閱讀 2533·2021-10-15 09:40
閱讀 1001·2021-10-14 09:42
閱讀 3475·2021-09-22 15:59
閱讀 888·2021-09-02 09:47
閱讀 2367·2019-08-30 15:54
閱讀 1438·2019-08-29 17:14
閱讀 399·2019-08-29 15:15