前後端分離——資料mock

小小冰發表於2018-08-10

Mock的方式

  • 在client端處資料mock
  • 在server端mock(json-server與faker.js)
  1. 第一種方式攔截了請求的發出,直接返回mock的資料,而第二種方式請求則真實地發出,只是在server端進行route攔截
  2. 前後端分離的方式,就是在傳統開發模式中加了一個node層,這樣資料mock完全可以在node server端完成

client mock

  1. 攔截所有請求
  2. 進行url規則匹配
  3. 匹配對的,返回mock資料
  4. 匹配不對的,走原本流程

mock.js

1.概念

mock.js是一個模擬資料生成器,幫助前後端分離。它可以根據資料模版生成模擬資料,模擬Ajax請求,生成隨機資料返回。

2.使用語法

Mock.js 的語法規範包括兩部分

  • 資料模板定義規範
  • 資料佔位符定義規範

詳細請看:mock.js文件連結

// 記錄資料模板。當攔截到匹配 rurl 的 Ajax 請求時,將根據資料模板 template 生成模擬資料,並作為響應資料返回。
Mock.mock( rurl, rtype, function( options ) )

rurl
可選。

表示需要攔截的 URL,可以是 URL 字串或 URL 正則。例如 /\/domain\/list\.json/、'/domian/list.json'。

rtype
可選。

表示需要攔截的 Ajax 請求型別。例如 GETPOSTPUTDELETE 等。

template
可選。

表示資料模板,可以是物件或字串。例如 { 'data|1-10':[{}] }、'@EMAIL'function(options)
可選。

表示用於生成響應資料的函式。

options
指向本次請求的 Ajax 選項集,含有 urltypebody 三個屬性,參見 XMLHttpRequest 規範。

複製程式碼

示例

Mock.mock('/api/getName', { name: 'Jack', 'age|10-20': 10 });
複製程式碼

3. 模板語法

1)資料模板定義規範(例舉)

'name|min-max': string

Mock.mock({
  "string|1-10": "★"
})

// result
{
  "string": "★★★"
}
複製程式碼

'name|count': string

Mock.mock({
  "string|3": "★★★"
})

// result
{
  "string": "★★★★★★★★★"
}
複製程式碼

2)Mock.Random Mock.Random 是一個工具類,用於生成各種隨機資料。

Mock.Random 的方法在資料模板中稱為『佔位符』,書寫格式為 @佔位符(引數 [, 引數]) 。

var Random = Mock.Random
Random.email()
// => "n.clark@miller.io"
Mock.mock('@email')
// => "y.lee@lewis.org"
Mock.mock( { email: '@email' } )
// => { email: "v.lewis@hall.gov" }

複製程式碼

// Random.datetime()
Random.datetime()
Mock.mock('@datetime')
Mock.mock('@datetime()')

// Random.datetime( format )
Random.datetime('yyyy-MM-dd A HH:mm:ss')
Random.datetime('yy-MM-dd a HH:mm:ss')
Random.datetime('y-MM-dd HH:mm:ss')
Random.datetime('y-M-d H:m:s')

Mock.mock('@datetime("yyyy-MM-dd A HH:mm:ss")')
Mock.mock('@datetime("yy-MM-dd a HH:mm:ss")')
Mock.mock('@datetime("y-MM-dd HH:mm:ss")')
Mock.mock('@datetime("y-M-d H:m:s")')

Mock.mock('@datetime("yyyy yy y MM M dd d HH H hh h mm m ss s SS S A a T")')

//result
// Random.datetime()
"1984-03-11 21:34:12"
"2011-07-11 01:17:12"
"2007-03-25 16:31:51"

// Random.datetime( format )
"2018-01-27 AM 01:57:13"
"98-09-12 pm 21:34:08"
"71-06-03 07:13:40"
"15-1-20 11:58:41"

"1991-09-17 PM 15:41:03"
"99-09-11 am 01:00:15"
"71-03-21 10:16:52"
"14-12-10 16:32:53"

"1976 76 76 09 9 29 29 06 6 06 6 12 12 33 33 184 184 AM am 212796753184"

複製程式碼

4. 缺點

無法攔截fecth請求

fetch-mock

1. 概念

攔截fecth請求,進行mock資料返回

2. 模板語法

fetchMock.mock(matcher, response)
複製程式碼

常用:

fetchMock.once() //限制了只被呼叫一次
fetchMock.restore()  //恢復其unstubbed fetch()狀態和清除所有資料記錄
複製程式碼

fetch-mock文件及對應api

3. 用法

  1. 安裝npm install mockjs
  2. 需要安裝fetch-mock包--yarn add fetch-mock,這個包主要用來包裝fetch
  3. 註冊mock 攔截資訊的,應該是在App入口的位置
if(process.env.__DEV__) {
    require('./mock/todolist')
}
複製程式碼
  1. 主要增加了mock資料夾,todolist.js是模擬資料
import FetchMock from 'fetch-mock';
FetchMock.mock('*', (url, options) => {
    //解析獲取opt
    if(opt==='9'){
        return {
           // mock資料
        };
    }
    if(opt==='155'){
        return {
           // mock資料
                    };
    }
    else {
        //恢復其unstubbed fetch()狀態和清除所有資料記錄
        FetchMock.restore();
        return fetch(url, options);
    }
    // FetchMock.restore();
    // return fetch(url, options);
});
複製程式碼

3. 專案的業務規則

專案目前情況:同一個url請求,通過opt進行判斷呼叫哪個業務介面,因此無法直接使用url進行區分匹配,需要更詳細的判斷

實際請求程式碼

params.opt = opt

let dataString = ''
let index = 0

const keys = Object.keys(params)
keys.forEach((key) => {
    if (index != 0) {
        dataString += '&'
    }
    index++
    const data = params[key]
    const encodeData = encodeURIComponent(data)
    dataString += `${key}=${encodeData}`
})

// opt最終會合併到dataString中,因此使用的時候,需要解析


let fetchPromise = fetch(url, {
            method: 'post',
            body: dataString,
            headers: header,
        }).then((response) => {
            if (response.ok) {
                return response.json()
            } else {
                throw new Error('網路錯誤')
            }
        })
複製程式碼

fetch-mock中

FetchMock.mock('*', (url, options) => {

	var dataString = options.body;
	var array = dataString.split("&")

	var opt;
	for (var temp of array) {
        	var temps = temp.split("=")
        	var key = temps[0]
        	var value = decodeURIComponent(temps[1])
	
        	if (key === "opt") {
        	    opt = value;
        	}
        	
    }

	if (opt === 195) {
		// 進行轉發請求
	} else {
	    FetchMock.restore();
		// 走正常請求
	}
})
複製程式碼

server mock

1. 簡單構建一套mock-server

為了更好的分工合作,讓前端能在不依賴後端環境的情況下進行開發,其中一種手段就是為前端開發者提供一個 web 容器,這個本地環境就是 mock-server

2. 一個比較好的 mock-server 該有的能力

  • 與線上環境一致的介面地址,每次構建前端程式碼時不需要修改呼叫介面的程式碼
  • 所改即所得,具有熱更新的能力,每次增加修改 mock 介面時不需要重啟 mock 服務,更不用重啟前端構建服務
  • 能配合 Webpack
  • mock 資料可以由工具生成不需要自己手動寫
  • 能模擬 POST、GET 請求

3. 使用json-server模擬伺服器API

以 json-server 作為 mock 伺服器, mock.js 生成mock 資料,json-server支援各種GET/POST/PUT/DELETE的請求

json-server文件

簡單使用

1)安裝json-server npm install -g json-server 2)發起fecth請求


import FetchMock from 'fetch-mock';

//其他路由使用原生fetch
FetchMock.mock('*', (url, options) => {
    //opt解析
    var array = options.body.split("&")
    var opt;
    for (var temp of array) {
        var temps = temp.split("=")
        var key = temps[0]
        var  value = temps[1]
        if(key==='opt'){
            opt = value
        }
    }
    
    //opt匹配,發出fecth請求,進行mock資料返回
    if(opt==='9'){
        FetchMock.restore();
        return fetch('http://localhost:53000/data');
        
    }
    if(opt==='155'){
        FetchMock.restore();
        return fetch('http://localhost:53000/list');
        
    }
    else {
        FetchMock.restore();
        return fetch(url, options);
    }
    // FetchMock.restore();
    // return fetch(url, options);
});

複製程式碼

3)生成一個json.js檔案,結合mock.js動態生成模擬資料

var Mock = require('mockjs');

module.exports = () => {
    // 使用 Mock
    var datas = Mock.mock({
        data:
            {
                //mock資料
            }
        ,
        list:{
                //mock資料
                "error": 0,
                "message": "success",
                'capitalDetails|30': [
                    {
                        //mock.js動態生成模擬資料
                        "summary": "@ctitle",
                        "time": "@datetime",
                    }
                ]
              }
    });
    // 返回的data會作為json-server的資料
    return datas;
};

複製程式碼

4)啟動json-server ,把一個js檔案返回的資料託管成web服務 json-server --watch --port 53000 json.js

成功時控制檯輸出:


shubing-mac:mock admin$ json-server --watch --port 53000 json.js

  \{^_^}/ hi!

  Loading json.js
  Done

  Resources
  http://localhost:53000/data
  http://localhost:53000/list

  Home
  http://localhost:53000

  Type s + enter at any time to create a snapshot of the database
  Watching...

複製程式碼
缺點

每次修改資料模版時,必須重新啟動mock伺服器

4.使用Faker.js

自動生成大量fake的json資料,作為後端資料

參考:github.com/marak/Faker…

相關文章