Vue实战(三)Mock服务JSON Server

本文是Vue实战系列的第三篇文章,主要介绍Falcon项目所依赖的Mock服务JSON Server。
Falcon项目地址:https://github.com/thierryxing/Falcon

前言

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

前后端协作的效率瓶颈

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

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

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

理想情况

那么上面的这种情况能否避免呢?答案是肯定的。关于前后端协作的理想状态,我认为是:

开始前

在项目开始前各个端的开发同学坐在一起干两件事:

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

开发中

到此为止,双方分开,前端去写UI部分的功能,涉及到后端接口的全部由Mock服务给出,前端在Mock服务中增加自己所需要的各种Json数据,模拟各种状态的逻辑处理。

联调阶段

最后联调时将Mock服务的地址换成后端联调环境的地址,即可完成全部功能,中间不存在等待的情况。由于双方都不会被打断,团队效率由此提升。

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

Mock服务

如果要达到以上描述的理想情况,前端同学需要在开发中引入Mock服务,这样可以最大限度的不依赖后端输出,从而避免了等待。
一个标准的Mock服务需要满足如下条件:

  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数据,比如:


  "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服务和mock服务了。
如果我想访问第一步中配置的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请求转发到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文件,如下图
Mock.png
  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: ''
  })
})

关于JSON Server完整的例子在此:
https://github.com/thierryxing/Falcon/tree/mock

结语

经过本人及团队内部实际使用,前端同学完全可以在不依赖后端的情况下,完成所有的界面和功能编写。
下一步,准备将其推广到移动客户端团队中使用。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,847评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,208评论 1 292
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,587评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,942评论 0 205
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,332评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,587评论 1 218
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,853评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,568评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,273评论 1 242
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,542评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,033评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,373评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,031评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,073评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,830评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,628评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,537评论 2 269

推荐阅读更多精彩内容