腾讯抢金达人项目中的前后端协作

蚊子前端博客
发布于 2020-01-08 00:55
在基于node同构直出的抢金达人项目中,前端是如何与后端进行协作的呢,如何模拟接口的各种情况呢,都考虑了哪些方案呢?

在前后端的协作过程中,通常都是并行开发的状态,那么在后端接口还没有开发完毕时,前端的业务逻辑工作就很难展开。因此也就有很多模拟接口数据的方式,这些方式各有个的优缺点:

  • 直接在代码中模拟接口数据:侵入业务逻辑,在后期需要删除这些模拟数据;

  • fiddler 替换文件:页面接口比较多时,需要替换的文件比较多;

  • fs 模块读取 json 文件:若是长列表的话,需要造的数据很多;

  • mockjs:避免上述方式的缺点,但无法校验参数是否缺失;

  • service worker:基于 service worker 可以拦截前端的请求,并构建假数据返回,但无法拦截 node 端发起的请求;

方式校验参数合法性切换环境方便前后端请求均可不修改业务代码模拟数据方便
直接在业务代码
中写接口数据
fiddler 替换文件 yes
fs 读取 json 文件 yesyes
mockjs yesyesyes
sw yes

我们理想的状态是:

  1. 提前校验请求接口中参数的合法性,是否缺失某些参数等;

  2. 切换环境方便,既可以使用模拟数据,也可以使用测试环境中的数据,同时也可以用正式环境中的数据进行检验;

  3. 可以拦截前后端均发起的请求,并尽量少的修改业务代码;

  4. 生成的模拟数据方便,假如接口中要返回前 1000 名用户的数据,总不能在 json 文件中写 1000 条数据;

上面的这几种方式,在我们抢金达人项目中,均不适用,或者对原有逻辑改动太大,或者使用起来不方便。这里我根据我们项目的需要,基于 mockjs 并与 express 的结合,实现了一套模拟数据的方法。

1. 模拟数据并校验参数的合法性

把接口的数据全部写在 json 文件,然后通过 fs 模块进行读取的这种方式,在构造大量数据时非常不方便。因此我们基于 mockjs 来实现模拟的数据,几行代码就能实现排行榜等大量的模拟数据,同时,也可以模拟一些稍微极端的情况,例如用户的昵称长度过长等,这些数据在测试环境一般很少能遇到,或者在后端接口模拟的成本也会比较高。

COPYJAVASCRIPT

// rank-person.js Mock.mock({ "rank|1000": [ { "no|+1": 1, uin: () => Mock.Random.string(32), nick: () => Mock.Random.string(1, 20), face: () => faces[Mock.Random.integer(0, 3)], region: "INVALID", title: "初露锋芒", level: () => Mock.Random.integer(1, 20), score: () => Mock.Random.integer(1, 2000), winPercent: 86 } ] });

但是,纯基于 mockjs 数据的方式,我们无法提现获知接口参数的异常。当我们在匹配到接口请求后就返回数据,会降低对参数的敏感度。这里,我对配置文件进行改造,当前接口中需要的参数提前设定好,类似于 jQuery.validate 中的设定。

这里我们的排行榜接口里有个last参数,0 表示是本周的数据,1 表示是上周的数据:

COPYJAVASCRIPT

module.exports = { params: { last: { required: true, // 是否必须 type: "number", // 参数的类型 defaults: 0, // 默认值 min: 0, // 最小值 max: 1 // 最大值等 } } };

当 mock server 接收到请求后,会先校验参数的合法性,若参数不合法直接返回。其实我们排行榜的 last 参数不是必传项,不传时即默认是 0,但我们在这里测试时改为必传,只要不传 last 参数即为参数不合法:

mock校验参数-蚊子的博客-蚊子的前端博客

当参数校验通过后,才会返回后面模拟的数据:

mock模拟的数据-蚊子的博客-蚊子的前端博客

2. 数据环境的切换

我们在上面的图中可以看到,当 mock 字段为"mock"时,读取模拟的数据,是不是一定要加一个 mock="mock"的参数才能去读模拟的数据呢?

这个要看咱们项目到什么状态了,当项目还在前提开发阶段时,大部分接口都还没有完成,这里我们可以将接口默认指向到模拟数据,mock="tes