json-server + mock.js搭建先后端分离的mock服务

前言:

作前端的应该都知道作页面的时候,当后端已经定义好了接口,但提供不了数据服务的时候,做为前端的你搭建页面是很痛苦的。 为此搭建一个能够mock数据的本地服务是颇有必要的。前端

用到的工具库:json-server提供服务。mockjs提供模拟的数据。node

本文的目录结构以下:webpack

1、实践

一、安装依赖web

npm install json-server mockjs --D
复制代码

二、编写db.json路由对应表npm

这是一个api路径和路径对应返回的内容组成的一个文件,好比:json

{
  "user_info": {
    "id": 1000,
    "course_name": "马连白米且",
    "autor": "袁明",
    "college": "金并即总变史",
    "category_Id": 2
  }
}
复制代码

上面的user_info就是你的api接口路径,后面的value值就是这个接口返回的内容.后端

假如你本地起了一个json-server服务,http://localhost:6666,api

那么你访问http://localhost:6666/user_info获得的就是如下内容:数组

{
  "id": 1000,
  "course_name": "马连白米且",
  "autor": "袁明",
  "college": "金并即总变史",
  "category_Id": 2
}
复制代码

但问题来了: 这样简单的定义一个db.json文件,你每次访问http://localhost:6666/user_info的时候,获得的都是同一份数据,它不会变。 这不是咱们想要的效果。咱们想要每次访问都获得不同的数据。bash

三、编写每次都会变化的mock数据

mock/mockDB/test.js

// 引入mock.js
let Mock = require('mockjs');
let Random = Mock.Random;

// 编写一个函数,这个函数利用mock.js动态生成mock数据
// 我看到不少教程这里是直接输出一个对象的,这样每次访问获得的都是一样的数据。不符合预期,
// 咱们这里用函数包装,每次访问api的时候就执行一次该函数,获得的就是新的mock数据了
function testList() {
  const monitorList = [];
  for (var i = 0; i < 3; i++) {
    monitorList.push(
      Mock.mock({
        userid: '25788869998_1562054852076593528',
        appid: Random.natural(100, 3000),
        content: Random.cparagraph(2, 4),
        timestamp: 1562054852,
      })
    );
  }
  
  // 这里返回你想要的数据格式
  return {
    success: true,
    data: monitorList,
    message: '获取数据成功',
  };
}

// 以api路径为值,将testList函数暴露出去
exports.user_info = testList;
复制代码

四、编写组装db.json文件的代码

如上文所说,json-server须要一个json文件作路由配置表,格式以下:

{
  "user_info": {
    "id": 1000,
    "course_name": "马连白米且",
    "autor": "袁明",
    "college": "金并即总变史",
    "category_Id": 2
  }
}
复制代码

很是注意的是: 路由配置里,api路径为key值,返回的数据为value值,这个value必须是数组或者对象。不能是函数,下面的写法是会报错的。

{
  "user_info": function () {
    return {
        "id": 1000,
        "course_name": "马连白米且",
    }
  }
}
复制代码

但想要每次请求同一个接口,返回的都是不同的数据,这个value必须是函数才行。这就是咱们在mock/mockDB/test.js定义的是函数的缘由。由于json-server的原理应该是:拿到访问的路径,而后经过路由配置表找到对应的value值,最后返回给用户的。若是写死成一个对象,或者数组,那么每次访问获得的都是一样的数据。

mock/db.js

将mockDB文件夹全部的mock数据文件读取出来,组装成上面路由配置表的格式,再暴露出去。 这里能够用webpack提供的require.context读取全部文件,也能够用node的fs模块读取全部文件。这里我就不展开来写了。简单说一下流程。

// 引入mockDB文件夹下的文件,假若有如下文件
 let test1 = require('./mockDB/test.js');
 let test2 = require('./mockDB/test2.js');
 
 // 这里定义一个收集的对象
let dbJson = {
  func: {},
  json: {},
}
// 收集mock函数,在server.js会用到
dbJson.func = {
  ...test1,
  ...test2,
};

// 获取全部的api路径
let apiPath = Object.keys(dbJson.func);

// 组装json-server须要的路由表,这里为何都是空对象呢?
// 上面说过,路由表的value必须是对象或者数组。但咱们的mockDB文件夹下定义的都是mock函数,因此这里要保证路由表是正确的,就要从新组装一份符合格式的路由表。
apiPath.forEach(item => {
  dbJson.json[item] = {};
});

exports.dbJson = dbJson.json;
exports.dbFunc = dbJson.func;
复制代码

五、搭建json-server本地服务

const jsonServer = require('json-server');
// 建立json-server实例
const server = jsonServer.create();
const jsonDB = require('./db');
// 将路由配置表传入,生成路由表
const router = jsonServer.router(jsonDB.dbJson);
const middlewares = jsonServer.defaults();

// 这里比较重要。
// 目的是:从新定义路由返回的数据。就是说:每访问一个路由,返回response的时候,均可以通过router.render从新定义response数据
// 由于咱们在db.js里将mock函数收集到了dbJson.func对象里。
router.render = (req, res) => {
    // 根据请求的url,截取路径。
    // 例如:通常状况,res.url是/user_info?id=1234这样的格式。
    let end = req.url.indexOf('?');
    let apiName = req.url.slice(1, end) || '';
    // 根据apiName拿到对应的mock函数,而后返回mock函数生产的mock数据
    // 由于每次返回response的时候,都会执行一次该函数,因此获得的都是新的mock数据
    let response = dbJson.func[apiName] && dbJson.func[apiName]();
    res.send(response || {}));
};

server.use(middlewares);
// 导入路由
server.use(router);
// 在6666端口开服务
server.listen(6666, () => {
  console.log('JSON Server is running');
});
复制代码

六、启动服务

node mock/server.js
复制代码

七、结束语

这篇文章是我的的实践作法,若是有说的不对的地方,还望见谅、指正,谢谢

相关文章
相关标签/搜索