Vue實戰(zhàn)(三)Mock服務(wù)JSON Server

本文是Vue實戰(zhàn)系列的第三篇文章看峻,主要介紹Falcon項目所依賴的Mock服務(wù)JSON Server屑那。
Falcon項目地址:https://github.com/thierryxing/Falcon

前言

由于Jaguar服務(wù)目前還沒有任何的API輸出撒顿,一邊寫前端功能扯再,一邊寫后端API顯然不利于整體的項目進(jìn)展离熏。所以我計劃先定義好接口佳谦,然后將所有的API都先部署在一個Mock服務(wù)器上,等前端界面和功能流程完全走通后滋戳,再轉(zhuǎn)過頭來在Jaguar上編寫對應(yīng)的API钻蔑。
說到這里,不禁想到前后端協(xié)作一直存在的一個效率瓶頸奸鸯。

前后端協(xié)作的效率瓶頸

在前(客戶端)后端協(xié)作開發(fā)中咪笑,有不少影響效率的地方,其中最為典型的就是:

  1. 前端的界面和功能中娄涩,因為存在不少功能依賴后端數(shù)據(jù)接口的窗怒,所以需要等待后端給出。
  2. 后端接口給出后蓄拣,由于初期設(shè)計不合理扬虚,或聯(lián)調(diào)中遇到特殊情況,或需求有變動球恤,導(dǎo)致需要改寫部分接口邏輯辜昵,所以需要等待并重新聯(lián)調(diào)。

雖然每次等待的時間也許不長咽斧,但是這樣的等待多了之后堪置,勢必會造成開發(fā)時間變得支離破碎躬存,開發(fā)流程常常中斷,而一旦中斷舀锨,重新進(jìn)入開發(fā)狀態(tài)也需要花一定的時間岭洲,相信大家對此都有所體會。
其帶來的嚴(yán)重后果就是雁竞,時間一點一點被浪費掉了钦椭,實際的開發(fā)時間比預(yù)計的要長出不少,更慘的是由于項目的工期之前已經(jīng)定好碑诉,所以大家就只能加班了彪腔,由于這樣的“教訓(xùn)”,大家在下次估算時間的時候进栽,往往會增加更多的Buffer德挣,從而導(dǎo)致整個團(tuán)隊的效率降低。

理想情況

那么上面的這種情況能否避免呢快毛?答案是肯定的格嗅。關(guān)于前后端協(xié)作的理想狀態(tài),我認(rèn)為是:

開始前

在項目開始前各個端的開發(fā)同學(xué)坐在一起干兩件事:

  1. 討論并定義好涉及到的接口唠帝,接口中需要的參數(shù)屯掖,字段,類型及各種狀態(tài)處理
  2. 形成一份接口文檔供多方使用

開發(fā)中

到此為止襟衰,雙方分開贴铜,前端去寫UI部分的功能,涉及到后端接口的全部由Mock服務(wù)給出瀑晒,前端在Mock服務(wù)中增加自己所需要的各種Json數(shù)據(jù)绍坝,模擬各種狀態(tài)的邏輯處理。

聯(lián)調(diào)階段

最后聯(lián)調(diào)時將Mock服務(wù)的地址換成后端聯(lián)調(diào)環(huán)境的地址苔悦,即可完成全部功能轩褐,中間不存在等待的情況。由于雙方都不會被打斷玖详,團(tuán)隊效率由此提升把介。

當(dāng)然,我描述的情況過于理想蟋座,在開發(fā)工程中難免會遇到不清楚或雙方都沒有考慮到的問題劳澄,需要隨時溝通的,即便是這樣蜈七,溝通清楚后前端修改Mock接口秒拔,后端修改業(yè)務(wù)接口即可,也不存在互相等待的情況,效率依然能有顯著的提升砂缩。

Mock服務(wù)

如果要達(dá)到以上描述的理想情況作谚,前端同學(xué)需要在開發(fā)中引入Mock服務(wù),這樣可以最大限度的不依賴后端輸出庵芭,從而避免了等待妹懒。
一個標(biāo)準(zhǔn)的Mock服務(wù)需要滿足如下條件:

  1. 提供能夠快速部署的基礎(chǔ)Http服務(wù)
  2. 能夠方便而靈活的配置路由,最好提供Restful支持
  3. 能夠方便的制造Mock數(shù)據(jù)
  4. 能夠處理簡單業(yè)務(wù)邏輯

JSON Server

這里推薦一款非常強(qiáng)大的Mock服務(wù)-JSON Server
https://github.com/typicode/json-server
JSON Server除了滿足以上4點外双吆,還可以:

  1. 支持路由參數(shù)過濾數(shù)據(jù)
  2. 支持分頁眨唬,排序和全文搜索
  3. 支持JSONP,支持Https
  4. 支持兩級路由資源嵌套

除此之外好乐,更加令人驚喜的是匾竿,其能夠和webpack做到無縫集成,可以通過配置和npm server一起啟動蔚万,安裝方法很簡單岭妖,不再贅述。配置方法如下:

第一步

在項目的根目錄下創(chuàng)建一個mock文件夾反璃,然后在里面增加一個db.json文件昵慌,在里面寫入所有的mock數(shù)據(jù),比如:


  "projects": [
    {
      "id": 4,
      "title": "Gengmei",
      "icon": "http://git.gengmei.cc/uploads/project/avatar/310/512-new.png",
    },
  "environments": [
    {
      "id": 1,
      "name": "Production",
      "projectId": 4
    },
    {
      "id": 2,
      "name": "Test",
      "projectId": 4
    }
  ]]

第二步

在package.json中的script中增加命令mock和mockdev:

 "scripts": {
    "dev": "node build/dev-server.js",
    "start": "node build/dev-server.js",
    "build": "node build/build.js",
    "mock": "json-server mock/db.json --port 9090", // 配置db路徑和端口
    "mockdev": "npm run mock & npm run dev",
  },

這樣就可以通過

npm run mockdev

的方式同時啟動npm服務(wù)和mock服務(wù)了淮蜈。
如果我想訪問第一步中配置的projects列表斋攀,那么地址為:

http://localhost:9090/projects

訪問id為4的project,地址為:

http://localhost:9090/projects/4

由于支持路由資源嵌套梧田,而environments下存在projectId為4的對象淳蔼,所以訪問id為4的project下的environments地址為:

http://localhost:9090/projects/4/enviroments

第三步

在config下的index.js中,增加proxyTable柿扣,將所有api請求轉(zhuǎn)發(fā)到mock server上

    proxyTable: { // proxy all requests starting with /api to jsonplaceholder
      '/api': {
        target: 'http://localhost:9090',
        changeOrigin: true,
        secure: false,
        pathRewrite: {
          '^/api': ''
        }
      }
    },

進(jìn)階

如果是一個簡單的項目,以上的三步基本滿足了對mock服務(wù)的基本要求闺魏,但是稍微復(fù)雜些的項目往往會遇到如下幾個情況:

  1. 默認(rèn)情況下JSON Server啟動命令中只能帶一個db.json未状,而實際項目中,如果所有接口數(shù)據(jù)都寫在一個json文件中析桥,顯然不利于維護(hù)司草,最好每類接口對應(yīng)一個json文件,如下圖
Mock.png
  1. 通常情況下泡仗,接口返回的數(shù)據(jù)不僅包含業(yè)務(wù)數(shù)據(jù)埋虹,還包含狀態(tài)數(shù)據(jù)和錯誤消息,一個常見的接口返回數(shù)據(jù)格式如下:
{
    data: {}, //業(yè)務(wù)數(shù)據(jù)
    status: 0,
    msg: ''
  }

那么不可能把這些數(shù)據(jù)寫在每個mock接口中娩怎,維護(hù)起來成本太高搔课,所以需要找一個地方統(tǒng)一處理。

為了解決以上兩個問題截亦,首先創(chuàng)建一個server.js文件爬泥,在里面編寫對應(yīng)的邏輯:

const jsonServer = require('json-server')
const server = jsonServer.create()

// Support middleware
const middleware = jsonServer.defaults()
server.use(middleware)

// 支持加載多個db json文件
const _ = require('underscore')
const path = require('path')
const fs = require('fs')
const mockDir = path.join(__dirname, 'data')
const base = {}
const files = fs.readdirSync(mockDir)
files.forEach(function (file) {
  _.extend(base, require(path.resolve(mockDir, file)))
})
const router = jsonServer.router(base)
server.use(router)

// 返回自定義格式數(shù)據(jù)
router.render = (req, res) => {
  console.log(res.locals.data)
  res.jsonp({
    data: res.locals.data,
    status: 0,
    msg: ''
  })
}

server.listen(9090, () => {
  console.log('JSON Server is running')
})

同時柬讨,修改package.json中的script為:

 "scripts": {
    "dev": "node build/dev-server.js",
    "start": "node build/dev-server.js",
    "build": "node build/build.js",
    "mock": "node mock/server.js", 
    "mockdev": "npm run mock & npm run dev",
  },

除此之外,簡單的數(shù)據(jù)校驗袍啡,用戶權(quán)限驗證等邏輯也可以寫到server.js中踩官,如:

server.use((req, res, next) => {
 if (isAuthorized(req)) { // add your authorization logic here
   next() // continue to JSON Server router
 } else {
   res.sendStatus(401)
 }
})

Post請求

對于Post請求,需要在server.js中進(jìn)行處理境输,比如:訪問登錄接口/account/login之后蔗牡,返回當(dāng)前登錄用戶的信息。
首先在db中增加返回的信息內(nèi)容:

  "login": {
    "id": 33,
    "name": "邢天宇",
    "avatar_url": "https://adminlte.io/themes/AdminLTE/dist/img/user2-160x160.jpg",
    "created_at": "17 Aug 16:22",
    "platform": "ios"
  },

然后在server.js中增加如下代碼:

// 處理登錄邏輯
server.post('/account/login', function (req, res) {
  let db = router.db 
  let data = db.get('login').value() //這里的login就是db中的key
  res.jsonp({
    data: data,
    status: 0,
    message: ''
  })
})

關(guān)于JSON Server完整的例子在此:
https://github.com/thierryxing/Falcon/tree/mock

結(jié)語

經(jīng)過本人及團(tuán)隊內(nèi)部實際使用嗅剖,前端同學(xué)完全可以在不依賴后端的情況下辩越,完成所有的界面和功能編寫。
下一步窗悯,準(zhǔn)備將其推廣到移動客戶端團(tuán)隊中使用区匣。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市蒋院,隨后出現(xiàn)的幾起案子亏钩,更是在濱河造成了極大的恐慌,老刑警劉巖欺旧,帶你破解...
    沈念sama閱讀 218,682評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件姑丑,死亡現(xiàn)場離奇詭異,居然都是意外死亡辞友,警方通過查閱死者的電腦和手機(jī)栅哀,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,277評論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來称龙,“玉大人留拾,你說我怎么就攤上這事■曜穑” “怎么了痴柔?”我有些...
    開封第一講書人閱讀 165,083評論 0 355
  • 文/不壞的土叔 我叫張陵,是天一觀的道長疫向。 經(jīng)常有香客問我咳蔚,道長,這世上最難降的妖魔是什么搔驼? 我笑而不...
    開封第一講書人閱讀 58,763評論 1 295
  • 正文 為了忘掉前任谈火,我火速辦了婚禮,結(jié)果婚禮上舌涨,老公的妹妹穿的比我還像新娘糯耍。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,785評論 6 392
  • 文/花漫 我一把揭開白布谍肤。 她就那樣靜靜地躺著啦租,像睡著了一般。 火紅的嫁衣襯著肌膚如雪荒揣。 梳的紋絲不亂的頭發(fā)上篷角,一...
    開封第一講書人閱讀 51,624評論 1 305
  • 那天,我揣著相機(jī)與錄音系任,去河邊找鬼恳蹲。 笑死,一個胖子當(dāng)著我的面吹牛俩滥,可吹牛的內(nèi)容都是我干的嘉蕾。 我是一名探鬼主播,決...
    沈念sama閱讀 40,358評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼霜旧,長吁一口氣:“原來是場噩夢啊……” “哼错忱!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起挂据,我...
    開封第一講書人閱讀 39,261評論 0 276
  • 序言:老撾萬榮一對情侶失蹤以清,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后崎逃,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體掷倔,經(jīng)...
    沈念sama閱讀 45,722評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,900評論 3 336
  • 正文 我和宋清朗相戀三年个绍,在試婚紗的時候發(fā)現(xiàn)自己被綠了勒葱。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,030評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡巴柿,死狀恐怖凛虽,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情广恢,我是刑警寧澤凯旋,帶...
    沈念sama閱讀 35,737評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站袁波,受9級特大地震影響瓦阐,放射性物質(zhì)發(fā)生泄漏蜗侈。R本人自食惡果不足惜篷牌,卻給世界環(huán)境...
    茶點故事閱讀 41,360評論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望踏幻。 院中可真熱鬧枷颊,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,941評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至题造,卻和暖如春傍菇,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背界赔。 一陣腳步聲響...
    開封第一講書人閱讀 33,057評論 1 270
  • 我被黑心中介騙來泰國打工丢习, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人淮悼。 一個月前我還...
    沈念sama閱讀 48,237評論 3 371
  • 正文 我出身青樓咐低,卻偏偏與公主長得像,于是被迫代替她去往敵國和親袜腥。 傳聞我的和親對象是個殘疾皇子见擦,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,976評論 2 355

推薦閱讀更多精彩內(nèi)容