🌙 接口联调那些事儿
🌙 1.背景
在 2005 年,Google 通过其 Google Suggest 使 AJAX(Ajax维基百科 (opens new window)) 变得流行起来之后,前端迎来了新的纪元。
随着前后端分离,前端地位也日益提升,但是也暴露了新的问题——前后端联调。🐛
🌙 2.前后端联调
🌙 2.1 青铜阶段
犹记当年,我还是一个懵懂的前端小白,拿着后端大佬给的接口不知所措。。。留下了没有技术的😂🙈
此时,一般都会结对编程,前后端面对面、手把手(咳!),“接口定义。。。”、“字段含义。。。”。
一般复杂的接口估计需要大半天联调时间。
🌙 2.2 黄金阶段
这个阶段,一般不会结对编程了(妹子除外哈🙈, go die!)。
后端会把mock的数据copy一份,一般是一个JSON串,丢给前端,让前端自己玩儿。厉害一点的前端会启动一个Node服务(比如express),模拟后端接口的URL、methods、response等,已经非常接近真实的接口了。
// 加载 expres 模块
const express = require('express');
// 创建一个 app 对象
const app = express();
// 通过中间件监听指定的路由
app.get('/data', (req, res) => {
res.send('hello world!世界,你好!');
// res.end('hello world!世界,你好!')
});
// 启动服务,监听8088端口
app.listen(8088, () => {
console.log('http://localhost:8088');
})
2
3
4
5
6
7
8
9
10
11
12
13
🌙 2.3 钻石阶段
此时,一般会有一个专门定义接口的后端设计(俗称SE),把接口文档设计OK,前后端根据这个接口文档去定义接口或页面。这个SE一般都是大哥大,业务和代码都很溜。
一般,前后端都玩的非常溜了,大家没必要时间浪费在接口联调上。后端大佬一般会把mock接口定义在API
直通车上,或者使用其他工具,比如Doclever
、Yapi
、 EasyMock
等。前端根据这些工具去获取所需的接口。
前端甚至可以使用MockJS
,在项目中拦截真实的接口,自定义各种场景下的数据,以便覆盖各种场景,比如:页面性能测试、压力测试(数据量很大)、边缘测试(不常见的场景)等。这样一来,测试也很轻松了。
🌙 2.4 王者阶段
俗称的全栈(干),前后端一个人搞定,这样就没什么接口联调的扯🥚了!
🌙 3.推荐使用MockJS
生成随机数据,拦截 Ajax 请求 (opens new window):
数据类型丰富:支持生成随机的文本、数字、布尔值、日期、邮箱、链接、图片、颜色等。
拦截 Ajax 请求:不需要修改既有代码,就可以拦截 Ajax 请求,返回模拟的响应数据。安全又便捷
一句话,真香啊!
🌙 3.1 安装
- 使用Random CLI
# 全局安装
npm install mockjs -g
# 执行
random url
# => http://rmcpx.org/funzwc
# 帮助
random -h
2
3
4
5
6
7
8
9
- 在项目中使用
npm install mockjs -D
🌙 3.2 在react-ts项目中使用
在scr目录下建立
mock
目录,新建index.ts
在
app.ts
中引入
import './mock'
// 为了在开发阶段避免部署时需要删除mock数据,建议按一下方式处理:
// 生产环境mock数据不打包
if (process.env.NODE_ENV === 'development') {
require('./mock');
}
2
3
4
5
6
7
8
- 在
mock
目录下新建test.ts
:
// 引入 Mock
import Mock from 'mockjs';
// 默认拦截get请求
Mock.mock(
'、mock/test',
{
// 属性 data 的值是一个数组,其中含有 1 到 10 个元素
'data|1-10': [
{
// 年龄1-100随机
'age|1-100': 0,
// 性别随机枚举一个
'gender|1': ['男','女','未知'],
// 随机中文名
'name': '@cname',
// 随机名字
'nickName': '@name',
// 随机生日
'birthday': '@date',
// 随机省份
'province': '@province',
},
],
}
);
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
注意:
'age|1-100': 0,
中|
前后不可有空格。
然后在mock/index.ts
中引入:
import './test'
🌙 3.3 拦截请求
API解读:参考
Mock.mock(rurl?, rtype?, template|function(options))
(opens new window)rurl
:可选,表示需要拦截的 URL,可以是 URL 字符串或 URL 正则。例如/\/domain\/list\.json/
、/domian/list.json
rtype
:可选,表示需要拦截的 Ajax 请求类型。例如 GET、POST、PUT、DELETE 等。template
: 可选,表示数据模板,可以是对象或字符串。例如{ 'data|1-10':[{}] }
、@EMAIL
。function(options)
:可选,表示用于生成响应数据的函数。options
指向本次请求的Ajax
选项集,含有url
、type
和body
三个属性,参见 XMLHttpRequest 规范 (opens new window)。
拦截GET请求:
import Mock, { Random } from 'mockjs';
Mock.mock(
'/mock/test/get',
'get',
() => {
const data = [];
for (let i = 0; i < 5; i++) {
data.push({
image: Random.image('1200x140',getRandomColor(),'mock随机图片测试'),
id: Random.id(),
picLink: Random.url(),
name: Random.name(),
});
}
return data;
}
);
function getRandomColor() {
return (
'#' +
'0123456789abcdef'
.split('')
.map(function(v, i, a) {
return i > 5 ? null : a[Math.floor(Math.random() * 16)];
})
.join('')
);
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
- 拦截POST请求:
import Mock from 'mockjs';
// 拦截post请求
Mock.mock('/mock/test/post', 'post', {
'status|1': [200, 500],
'data|1': ['OK', 'ERROR', ''],
});
2
3
4
5
6
7
8
- 拦截带参数的请求,如
/mock/post/user?id=12656
import Mock from 'mockjs';
let data = {
"code": 0,
"data": {
"fullName": "@CNAME",
"userId": "@id",
}
};
Mock.mock(RegExp('/mock/post/user' + '.*'), "get", (options) =>{
// 调试
console.debug(data, options);
return Mock.mock(data);
});
2
3
4
5
6
7
8
9
10
11
12
13
14