如何在开发过程中搭建简单的假数据服务器

在开发一块新功能的过程中,我们通常会涉及到与后端接口联调的问题。新的界面、新的后端接口,这时候在开发的时候往往前端就很尴尬,后端不依赖前端,但是前端十分依赖后端。

大部分应用都会有或多或少地依赖后端数据,有的界面只需要简单搞个假数据传入即可,但是我们还需要应对很多复杂情况,比如:

  • 处理无数据、返回错误、各类非正常的状态;

  • 处理分页数据的情况;

  • 模拟一个请求中、请求失败、请求结果返回的情景;

这时候如果能够写一个简单的服务器,你请求真实的接口url,只需要给手机设置一个代理,就返回你设置的假数据。这样你就可以完全抛开其他依赖的顾虑,可以像正常情况一样开发、校验结果,而不是依赖写死在代码里的各种假逻辑(这样做也会为后面的开发带来一些隐患)。

实际上服务器本身的逻辑是非常简单的,但是要真正得搭建成你所需要的环境,需要一些复杂功夫。本文以[nodejs](http://blog.desmondyao.com
/fake-server/node)为例,具体描述一下如何在本机上搭建测试服务器。

使用node搭建起简单的服务器脚本

1. 安装

Unix 用户可以使用命令行安装nodejs。

Windows 用户可以直接下载安装包

安装成功后如果在命令行下输入node -v能够打印出版本信息,说明安装成功了。

2. 简单服务器

Node 服务器可以运行在“IP:PORT”上,我们可以通过如下代码来在127.0.0.1:2333端口上搭建起一个简单的服务器:

server.js

1
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


const http = require('http');

http.createServer( (req, res) => {

// 返回码200,返回头中标识内容为json

res.writeHead(200, {'Content-Type': 'text/json'});

let resp = {

code : 0,

time : 1469981217,

data : {

name : 'desmond',

gender : 'male'

}

};

res.end(JSON.stringify(resp)); // 将resp转换为JSON字符串返回。

}).listen(2333, '127.0.0.1', )

之后输入node server.js,然后我们到浏览器中访问localhost:2333就可以看见:

具体的信息可以参考Nodejs-http.

3. IDE配置

从IDE环境切换到脚本环境来写代码总会不顺手,推荐一个我认为比较容易上手的配置吧:

Nginx反向代理

nginx
搭建服务器的强大处之一就是它的代理能力,配置也十分简洁。

如果要模拟最终的请求的话,我们应该是原封不动的保留请求url: ‘www.desmond.com/api/something’。首先我们需要
在手机上设置代理,将ip配置到自己电脑上,端口配为80
。但是你的电脑识别到这个请求后,怎么让它导流到你的node服务器,这是一个问题。如果你代码写死的ip+端口来访问,未免有点太low了,我们既然折腾了这么多,那可以继续往下走一步:反向代理

反向代理,简而言之,就是一个分发请求的代理。前向代理
是直接发给目标服务器,但是它会做一些额外的处理工作。反向代理不一样,它自己相当于是一个服务器,请求到它手里,它根据请求去不同服务器上拉取数据。

1. 安装Nginx

Linux用户可以使用命令行:

1
2
3
apt-get update

apt-get install nginx

OSX用户可以用Homebrew:

1
brew install nginx

Windows用户可以下载安装包

2. 配置代理

我们希望针对’www.desmond.com/api/something’下的url交由node服务器(2333端口)处理,其他情况下继续发送,可以在nginx.conf里面这么配置(可以在命令行下输入nginx
-t找到配置文件位置):

1
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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47


server {

listen 本机ip:80;

server_name www.desmond.com;

#charset koi8-r;

access_log /Users/desmond/Nginx/api.access.log;

error_log /Users/desmond/Nginx/api.error.log;

location / { //默认情况原路继续

resolver 8.8.8.8;

proxy_pass http://$http_host$request_uri;

proxy_set_header Host $http_host;

proxy_connect_timeout 5;

}

location /api { //检测到api路径下的,转发到端口2333

proxy_pass http://localhost:2333;

}

#error_page 404 /404.html;

# redirect server error pages to the static page /50x.html

#

error_page 500 502 503 504 /50x.html;

location = /50x.html {

root html;

}

}

这里如果希望原路继续的那些url域名解析配合你的host(此处使用8.8.8.8来做DNS解析),你可以参考[StackOverflow的一个提问](http://stackoverflow.com/questions/8305015
/when-using-proxy-pass-can-etc-hosts-be-used-to-resolve-domain-names-instead-
of)。

这样一来,你所有手机上访问的www.desmond.com/api/something就导到你的nodejs服务器上啦,尽情配置假数据来测试吧~~

4. 配合Charles使用

如果使用Charles的话,手机上一般配的代理是”ip:8888”,那么此时需要做一件事:本地的host设置本机ip
www.desmond.com,这样才能保证 www.desmond.com域名下的请求被导流到nginx服务器,从而导流到自己的nodejs服务器上。

最终搭建

直接使用node,还是有一些繁琐的。既然我们的目的是“简单”,那么可以考虑一下使用express
。它封装了很多API,然呢使用起来非常方便。其中一项就是路由(Route)。它意思简单来说就是: www.desmond.com/api/a 由 a
的逻辑处理,www.desmond.com/api/b 由 b 的逻辑处理。

我相信一个新模块的服务器接口肯定不止一个,假如我们现在接口文档上写着:

1. 提交个人信息:www.desmond.com/api/personal

方法:POST

返回示例:

1
2
3
4
5
6
7
{

code : 0,

time : 1469981217

}

2. 获取未来n天天气信息:www.desmond.com/api/weather

方法:GET

参数:day 未来天数

返回示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

{

code : 0,

time : 1469981217,

data : {

items : [

date : '2016-08-02',

state : 'sunny'

],

//...

}

}

那么你可以使用来做一个简单的ROUTE+请求处理:

server.js

1
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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
const express = require('express');

const url = require('url');

let app = express();

app.post('/api/personal', function (req, res) { //针对/api/personal 的 post请求返回

    res.writeHead(200, {'Content-Type': 'text/json;charset=utf-8'});

    res.end(JSON.stringify({

code : 0,

time : 1469981217

}));

});

app.get('/api/weather', function (req, res) { //针对/api/weather 的 get请求返回

    res.writeHead(200, {'Content-Type': 'text/json;charset=utf-8'});

let count = url.parse(req.url, true).query.day; //解析传入的day参数

if(count) { //若有,根据day参数生成item

let tmpList = [];

let tmpDate = newDate();

for(let i = 0; i < count; i++ ) {

tmpDate.setDate(tmpDate.getDate() + 1);

tmpList.push({

date : `${tmpDate.getFullYear()}-${tmpDate.getMonth() +
1}-${tmpDate.getDate()}`,

state : `sunny - ${i}`

});

}

res.end(JSON.stringify({

code : 0,

time : 1469981217,

items : tmpList

}));

} else { //若无,则返回错误信息

res.end(JSON.stringify({

code : -1,

msg: 'you must send param \"day\"',

time : 1469981217

}));

}

});

app.listen(2333, function(req, res) {

    console.log(`You have run node host.`);

});

注意:不要忘记安装express,(npm install express –save)即可。

编辑结束后运行一下node server.js,你可以看到输出:

You have run node host.

这时我们可以尝试请求一下 localhost:2333,可以看到返回:

大功告成~~

如果希望node server一直在后台跑(使用node
server.js时shell会卡在当前运行中),可以使用ForeverJS

更简单的办法

如果不想折腾太多,可以直接写一个json静态文件去返回:

data.json

1
2
3
4
5
6
7
{

"code" : 0,

"time" : 1469981217

}

*注意:手写json的话,里面的 key 必须以字符串形式(双冒号包围)存在。

server.js

1
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
33
34
35
36
37
const fs = require('fs');

const express = require('express');

let app = express();

app.get('/api/weather', function (req, res) { //针对/api/weather 的 get请求返回

res.writeHead(200, {'Content-Type': 'text/json;charset=utf-8'});

fs.readFile('data.json', 'utf8', (err, data) => { //读取data.json

if(err) { //错误时返回异常

res.end(JSON.stringify({

code : -1,

msg : 'Read File error!'

}));

return;

}

res.end(data);

});

});

app.listen(2333, function(req, res) {

console.log(`You have run node host.`);

});

这样就非常简单,不过缺点就是无法动态地处理。

# 后端

评论

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×