前端使用Mock服务Json-server

前言

因为Jaguar服务目前尚未任何的API输出,一边写前端功能,一边写后端API显然不利于总体的项目进展。因此我计划先定义好接口,而后将全部的API都先部署在一个Mock服务器上,等前端界面和功能流程彻底走通后,再转过头来在Jaguar上编写对应的API。
说到这里,不由想到先后端协做一直存在的一个效率瓶颈。前端

先后端协做的效率瓶颈

在前(客户端)后端协做开发中,有很多影响效率的地方,其中最为典型的就是:node

  1. 前端的界面和功能中,由于存在很多功能依赖后端数据接口的,因此须要等待后端给出。
  2. 后端接口给出后,因为初期设计不合理,或联调中遇到特殊状况,或需求有变更,致使须要改写部分接口逻辑,因此须要等待并从新联调。

虽然每次等待的时间也许不长,可是这样的等待多了以后,势必会形成开发时间变得支离破碎,开发流程经常中断,而一旦中断,从新进入开发状态也须要花必定的时间,相信你们对此都有所体会。
其带来的严重后果就是,时间一点一点被浪费掉了,实际的开发时间比预计的要长出很多,更惨的是因为项目的工期以前已经定好,因此你们就只能加班了,因为这样的“教训”,你们在下次估算时间的时候,每每会增长更多的Buffer,从而致使整个团队的效率下降。webpack

理想状况

那么上面的这种状况可否避免呢?答案是确定的。关于先后端协做的理想状态,我认为是:ios

开始前

在项目开始前各个端的开发同窗坐在一块儿干两件事:git

  1. 讨论并定义好涉及到的接口,接口中须要的参数,字段,类型及各类状态处理
  2. 造成一份接口文档供多方使用

开发中

到此为止,双方分开,前端去写UI部分的功能,涉及到后端接口的所有由Mock服务给出,前端在Mock服务中增长本身所须要的各类Json数据,模拟各类状态的逻辑处理。github

联调阶段

最后联调时将Mock服务的地址换成后端联调环境的地址,便可完成所有功能,中间不存在等待的状况。因为双方都不会被打断,团队效率由此提高。web

固然,我描述的状况过于理想,在开发工程中不免会遇到不清楚或双方都没有考虑到的问题,须要随时沟通的,即使是这样,沟通清楚后前端修改Mock接口,后端修改业务接口便可,也不存在互相等待的状况,效率依然能有显著的提高。npm

Mock服务

若是要达到以上描述的理想状况,前端同窗须要在开发中引入Mock服务,这样能够最大限度的不依赖后端输出,从而避免了等待。
一个标准的Mock服务须要知足以下条件:json

  1. 提供可以快速部署的基础Http服务
  2. 可以方便而灵活的配置路由,最好提供Restful支持
  3. 可以方便的制造Mock数据
  4. 可以处理简单业务逻辑

JSON Server

这里推荐一款很是强大的Mock服务-JSON Server
https://github.com/typicode/json-server
JSON Server除了知足以上4点外,还能够:后端

  1. 支持路由参数过滤数据
  2. 支持分页,排序和全文搜索
  3. 支持JSONP,支持Https
  4. 支持两级路由资源嵌套

除此以外,更加使人惊喜的是,其可以和webpack作到无缝集成,能够经过配置和npm server一块儿启动,安装方法很简单,再也不赘述。配置方法以下:

第一步

在项目的根目录下建立一个mock文件夹,而后在里面增长一个db.json文件,在里面写入全部的mock数据,好比:

{
  "boardList": [
    {
      "title": "开放产品",
      "description": "开放产品是一款开放产品",
      "id": "car",
      "toKey": "analysis",
      "saleout": false
    },
    {
      "title": "品牌营销",
      "description": "品牌营销帮助你的产品更好地找到定位",
      "id": "earth",
      "toKey": "count",
      "saleout": false
    },
    {
      "title": "使命必达",
      "description": "使命必达快速迭代永远保持最前端的速度",
      "id": "loud",
      "toKey": "forecast",
      "saleout": true
    },
    {
      "title": "勇攀高峰",
      "description": "帮你勇闯高峰,到达事业的顶峰",
      "id": "hill",
      "toKey": "publish",
      "saleout": false
    }
  ]}

第二步

在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服务和mock服务了。

第三步

在config下的index.js中,增长proxyTable,将全部api请求转发到mock server上

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

进阶

若是是一个简单的项目,以上的三步基本知足了对mock服务的基本要求,可是稍微复杂些的项目每每会遇到以下几个状况:

  1. 默认状况下JSON Server启动命令中只能带一个db.json,而实际项目中,若是全部接口数据都写在一个json文件中,显然不利于维护,最好每类接口对应一个json文件,以下图

  1. 一般状况下,接口返回的数据不只包含业务数据,还包含状态数据和错误消息,一个常见的接口返回数据格式以下:
{
    data: {}, //业务数据
    status: 0,
    msg: ''
  }

那么不可能把这些数据写在每一个mock接口中,维护起来成本过高,因此须要找一个地方统一处理。

为了解决以上两个问题,首先建立一个server.js文件,在里面编写对应的逻辑:

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)

// 返回自定义格式数据
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",
  },

除此以外,简单的数据校验,用户权限验证等逻辑也能够写到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中进行处理,好比:访问登陆接口/account/login以后,返回当前登陆用户的信息。
首先在db中增长返回的信息内容:

"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: ''
  })
})

 

这是再次运行npm run mockdev时会发如今mock/data/文件夹内会产生一个db.json的文件,能够将须要的内容贴到文件内部,而后经过调用就能够达到访问的目的了。

 

 

本文摘抄于https://www.jianshu.com/p/7094c477207d     

相关文章
相关标签/搜索