利用mock提升效率

利用mock提升效率

谈到mock,就不得不讲先后端分离。理想状况下先后端不分离,由全栈的人以product和infrastructure的维度进行开发,效率是最高的。近些年来业务的复杂度愈来愈高,真正的全栈人才极为难招,企业只能退而求其次,对开发进行分工细化,让每一个人作本身最擅长的事,前端负责UI显示和交互,后端负责业务的逻辑、性能等,从而架构上达到更高的效率。同时因为分工的细化,致使先后端的沟通成本增长,代码的控制权一般在后端,一次小的修改可能致使先后端反复沟通,下降开发效率,就产生了先后端分离的方案。先后端分离经过约定好协议,使用约定的协议进行并行开发,将沟通最后阶段放在联调,节省了大量的时间。javascript

分离的表现主要是视图层的控制交给前端,对于一些偏应用类项目,使用ajax请求,先后端各负责本身的部分,直接达到分离状态,而一些展现类系统,受到seo和用户体验的影响,分离只能达到部分分离,如fis方案。不论是哪一种状态的分离,都须要进行协议约定,以达到业务的并行开发。对于前端来讲,开发的效果更多依赖于数据,想要最大程度的减小联调时间,就须要根据协议生成数据,这也就是mock的需求。html

使用mock开发流程

这里借用yapi的流程图(yapi表示mock服务):
前端

首先,先后端进行定制接口,定制完成后各自进行开发。前端的开发者使用mock数据进行开发,开发完成后进行真实环境的联调,找出开发中的问题,再进行测试、上线等流程。java

经常使用的mock方式

1. 代码层硬编码

直接数据写在代码中(或者独立的文件,代码中手动引入),修改代码跳过接口请求,直接使用数据。这种方式的最大问题是耦合性太强,业务代码中混杂了mock数据,每次正式提交都要保证代码数据指向是正确的,不然会产生神奇的结果。同时不是真正发出网络请求,和真实环境有差别。建议仅在没有其余方式的状况下才使用。node

2. 代码中针对使用的ajax库拦截

这种方式分为拦截到本地和拦截到其余服务器。相较于硬编码,拦截式下降了mock数据和业务代码的耦合性,只须要引入拦截的代码,将请求转发至本地,至本地文件或其余服务器。这种方案的主要问题是须要针对代码使用的各类库进行定制插件,初期成本高;同时有部分的代码入侵,须要保证入库代码正确。jquery

  • 拦截至数据文件:
    最典型的是Mock.js。这种方式实现了自由编写数据,灵活性比较大,并且mock的数据文件能够同步至仓库中,下次开发时。缺点是一样非网络请求,真实性不足。webpack

  • 拦截并改变请求:
    这种方式之因此出现是由于服务器的URL和本机的URL规则不一样,须要按照规则进行转换。这种方式与真实状况比较接近,同时产生了跨域,须要服务端提供对应的header。ios

3. 为全部接口统一添加前缀

这种方式在公用文件中直接添加接口前缀,依赖于特定的库功能(或者达到相同效果的代码结构)。同以前的拦截并改变请求相似,但更为简单一些,只改前缀就能够了,一样有代码入侵的问题。nginx

4. 使用其余工具

这种方式分为两种:使用本地或软件数据和代理转发git

  • 使用本地或软件数据:
    最经常使用的如:fiddler, charles, whistle等,能够将请求返回指定内容。主要问题是配置比较繁琐,全部操做都在本机,同步困难。

  • 代理转发:
    这种方式和真实环境极为接近,毕竟纯静态的文件,在服务端也是须要进行代理转发的。可以使用的工具就比较多了,使用支持代理转发的开发工具,或者使用上面提到的工具,一样可以将数据转发出去。这种方式最大的优势是:无跨域、能发出真实请求、与业务代码彻底隔离。

方案对比

对比以上几种方案,最优的选用代理转发方式,其次是代码拦截方式。拦截至数据文件有个优点就是能够将mock数据和仓库同步,但在不一样分支开发时Mock数据可能会冲突。代理转发和拦截至服务器使用最方便,但它须要mockServer。只视开发状况而定。

一些mock用工具

mock的实现很是多,基本上每套完善的前端开发工具都是自带mock的机制。近几年随着nodejs的流行,前端能够很是方便的实现本身的mockServer,因此想列举出全部的仍是很困难的,这里介绍一些知名字较高的工具。

1. swagger

  • 地址:[https://swagger.io/]
  • 介绍: 提到mock,就不得不提到swagger (https://swagger.io/)。它是一个极为流行的一个API设计开发工具,覆盖了从设计到文档到测试部署。它是这样介绍的:

    Swagger is the world’s largest framework of API developer tools for the OpenAPI Specification(OAS), enabling development across the entire API lifecycle, from design and documentation, to test and deployment.

在设计RESTFUL类型的API极为有用,它没有专门提供mock服务,但能够提供mock服务的server模板代码,可根据模板自行搭建mock-server。此外,还提供相关的API的JSON结构数据,配合相应的工具来实现相似的效果。

2. Mock.js

  • 地址:https://github.com/nuysoft/Mock/tree/refactoring
  • 介绍:THX团队出品,本地文件编写mock数据规则,适用于代码库拦截,以前较为流行的一个方案,不少工具都集成了Mockjs语法,目前仓库已经再也不更新。

3. rap2

  • 地址:https://github.com/thx/rap2-delos
  • 介绍:同THX团队出品,是rap0.x的升级版本,使用了nodejs和关系数据库开发,兼容mock.js语法。界面比较简洁,交互友好,支持界面式编辑API。但URL设计与原URL不一样,须要使用代码库拦截方式。

4. apiary

  • 地址:https://app.apiary.io/
  • 介绍:这款在国外用的比较多一些,功能也是比较强大:

    Apiary.io平台具备协同设计、即时API模拟、快速生成源码、自动测试和代码调试的开源设计工具,最重要的是能够在线模拟测试,由于该平台具有模拟服务器测试服务,能够把设计好的程序在线测试、验证。

5. easy-mock

  • 地址:https://easy-mock.com/
  • 介绍:搜车出品,rest api模拟,基于mockjs语法,可以从swagger生成简单数据。

6. yapi

  • 地址:http://yapi.qunar.com/getfamiliar.html
  • 介绍:这是去哪团队作的,使用了nodejs+mongodb方式开发,主要特性:

    • 基于 Json5 和 Mockjs 定义接口返回数据的结构和文档,效率提高多倍
    • 扁平化权限设计,即保证了大型企业级项目的管理,又保证了易用性
    • 相似 postman 的接口调试
    • 自动化测试, 支持对 Response 断言
    • MockServer 除支持普通的随机 mock 外,还增长了 Mock 指望功能,根据设置的请求过滤规则,返回指望数据
    • 支持 postman, har, swagger 数据导入
    • 免费开源,内网部署,信息不再怕泄露了

rap2和yapi的一些对比

接入mockServer

有了各类极为方便使用的mockServer,想要接入就很简单了。mockServer的通常使用规则:

  • URL相同,直接代理转发便可
  • URL后半部分相同,直接加上URL前缀便可
  • URL规则不一样,或须要身份认证,须要拦截转发

拦截式

拦截式针对的是使用一些封装过的ajax库,好比jquery、axios,或者使用fetch库。实现的方式各有不一样。若是使用的是支持拦截器模式(如axios),拦截代码就比较简单了,直接在拦截器中改变URL指向便可,指向mockServer或mockjs文件。见如下代码(如下代码是摘自rap或rap2等其余库)。

function wrapAxios(axios) {
  var url = ''
  var oldRequest = {}
  var routePassed = false
  axios.interceptors.request.use(function (config) {
      url = config.url
      config.url = "http://" + ROOT + '/mockjsdata/' + projectId + url;
      oldRequest = Object.assign({}, config)
      return config;
  }, function (error) {
      return Promise.reject(error);
  });

  axios.interceptors.response.use(function (res) {
      return res;
  }, function (error) {
      return Promise.reject(error);
  });
}

对于一些不支持拦截器的,或者原生的方法fetch,经过覆盖的方式实现(https://github.com/wenlonghuo/rap2-delos/blob/master/public/libs/fetch.rap.js):

;(function (RAP, fetch) {
  if (!fetch) {
    console.warn('当前环境不支持 fetch')
    return
  }
  if (!RAP) {
    console.warn('请先引入 RAP 插件')
    return
  }

  let next = fetch
  let find = (settings) => {
    for (let repositoryId in RAP.interfaces) {
      for (let itf of RAP.interfaces[repositoryId]) {
        if (itf.method.toUpperCase() === settings.method.toUpperCase() && itf.url === settings.url) {
          return Object.assign({}, itf, { repositoryId })
        }
      }
    }
  }
  window.fetch = function (url, settings) {
    // ajax(settings)
    if (typeof url === 'object') {
      settings = Object.assign({ method: 'GET' }, url)
    } else {
      // ajax(url) ajax(url, settings)
      settings = Object.assign({ method: 'GET' }, settings, { url })
    }

    var match = find(settings)
    if (!match) return next.call(window, url, settings)

    let redirect = `${RAP.protocol}://${RAP.host}/app/mock/${match.repositoryId}/${match.method}/${match.url}`
    settings.credentials = 'include'
    settings.method = 'GET'
    settings.dataType = 'jsonp'
    console.log(`Fetch ${match.method} ${match.url} => ${redirect}`)
    return next.call(window, redirect, settings)
  }
})(window.RAP, window.fetch)

使用这些插件的方法很简单,直接在html最后添加指向的script标签便可(部分拦截可能须要引入多个标签)。

修改全局URL式

这种状况适合mockServer请求中须要添加baseURL的类型。对于支持baseURL类型的库,设置baseURL便可。如baseURL为:

http://yapi.demo.qunar.com/mock/1304

咱们业务代码中请求的api为:

/weather/api

那么咱们实际请求的地址是:

http://yapi.demo.qunar.com/mock/1304/weather/api

因此咱们应该这么设置(以axios为例):

export default axios = new Axios({
    baseURL: process.env.NODE_ENV === 'development' ? 'http://yapi.demo.qunar.com/mock/1304' : 
})

若是是不区分环境的状况下,须要在提交前将baseURL设置为空,以避免影响仓库代码。

对于不支持baseURL的库,建议封装方法,单独保存baseURL。

代理转发式

代理转发实现的前提是你使用的开发工具支持转发,若是不支持,就须要使用Fiddler、charles等工具进行规则重写。下面举一些例子:

webpack-dev-server中:

proxy: {
  "/api": "http://localhost:3000"
}
proxy: {
  "/api": {
    target: "http://localhost:3000",
    changeOrigin: true
  }
}

注:changeOrigin是http-proxy设置选项,表示在请求头中将host转换为目标服务器的地址或IP,解决服务器出现请求地址找不到的问题。

nginx(应该没人用吧):

location /api {
    proxy_set_header X-Forwarded-Proto https;
    proxy_set_header Host $host;
    proxy_set_header X-Real-Ip $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Host $server_name;
    proxy_pass http://localhost:11011;
    proxy_redirect off;
}

fiddler中在右侧的tab页中选择autoResponder标签页。编辑rule分别输入

REGEX:^https://server\.example\.com/(.*)
http://www.target.com:3838/$1

mock的一些问题

  • mock不能替代联调。尽管mock数据再真实,也没法实现和后端接口同样的逻辑,部分逻辑检查或业务的问题只能联调才能发现。
  • mock不能替代测试。mock自己是为了加快开发速度,那些对于代码质量要求比较高的项目,mock服务只能提供一些case。

总结

使用mock前提是先后端有一个明确的接口协议,利用合适的工具才能提升开发效率。强大的mock服务可使你对开发的代码更为自信,即便没有后端,新手就能够经过mock熟悉以前的业务界面,或者查看一些表现特殊的界面,最大程度减小对后端的依赖。

上面介绍的几款mockServer有几种都是使用nodejs开发的。和其余语言开发的mock服务相比,json格式成为书写的主要格式,虽然用起来容易,但书写上并不方便(json5格式在某种程度上加强了书写体验,但相比yaml等格式仍是有所不足)。同时业务状况不一样,针对性的选择不一样的平台,推荐使用rap2和yapi,前者界面更为简洁,操做方便,后者功能更为强大。若是有特殊的须要,能够本身写一个,顺便练练手。

搭建一个属于本身的server

参考

【你是如何构建 Web 前端 Mock Server 的? - 莫池宇的回答 - 知乎
https://www.zhihu.com/question/35436669/answer/235608128

相关文章
相关标签/搜索