json-server 是什么?
我把这个词抛给一个后端好友时,他没用过查了下回复说:哦,原来是个mock 工具。
mock这词本意是模拟、糊弄
的意思。mock server工具,通俗来说,就是模拟服务端接口数据,一般用在前后端分离后,前端人员可以不依赖API开发,而在本地搭建一个JSON服务,自己产生测试数据。
顾名思义,json-server就是个存储json数据的server~
先献祭上json-server的github : github地址 。
1 下载安装
使用npm全局安装json-server:
npm install -g json-server
可以通过查看版本号,来测试是否安装成功:
json-server -v
2 创建json数据——db.json
既然是造数据,就需要创建一个json数据。
在任意一个文件夹下(此处假设我创建了一个myserver文件夹),进入到该文件夹里面,执行代码:
json-server --watch db.json
原本空空如也的文件夹里,就会多出一个db.json文件。
同时,根据执行代码结果的提示,我们可以访问 http://localhost:3000 (启动json-server后,点击才有效),看到如下页面:
可以分别点击
/posts
/comment
/profile
/db
链接,看看页面跳转后,观察地址栏变化和页面内容,你看到了什么?
没错,就是各自的json数据。
再比对myserver/db.json文件的数据,就可以发现: /db
就是整个的db.json数据包,而/posts
/comment
/profile
分别是db.json里面的子对象。
所以说,json-server把db.json 根节点的每一个key,当作了一个router。我们可以根据这个规则来编写测试数据。
json-server 默认是 3000 端口,我们也可以自己指定端口,指令如下:
json-server --watch db.json --port 3004
嗯,如果你很懒,觉得启动服务的这段代码有点长,还可以考虑db.json同级文件夹(也就是myserver文件夹)新建一个package.json,把配置信息写在里头:
{
"scripts": {
"mock": "json-server db.json --port 3004"
}
}
之后启动服务,只需要执行如下指令就可以了:
npm run mock
3 操作数据
我们先自己倒腾下 db.json 数据,比如现在是个水果商城,放点 用户信息 和 水果价格 信息:
{
"fruits": [
{
"id": 1,
"name": "apple",
"price": "33"
},
{
"id": 2,
"name": "orange",
"price": "8.88"
}
],
"users": [
{
"name": {
"username":"admin",
"nickname":"dachui"
},
"pwd": "123456"
}
]
}
要注意,数据格式符合JSON格式(尤其注意最后一个键值对后面不要有逗号)。如果数据格式有误,命令窗口会报错,可以根据错误提示进行修整。
接下来我们就可以GET, POST, PUT, PATCH or DELETE 方法来对数据进行操作。
(1)GET
首先,我们先来看GET操作。(以下会根据官方文档对所有GET操作做详细说明。)
浏览器地址访问就可以看做GET操作,所以不用写任何代码,我们就可以先来测试下 url -GET 操作。
常规获取:
http://localhost:3004/fruits
可以得到所有水果数据(对象数组):
[
{
"id": 1,
"name": "apple",
"price": "33"
},
{
"id": 2,
"name": "orange",
"price": "8.88"
}
]
过滤获取 Filter:
http://localhost:3004/fruits/1
可以得到指定id为1的水果(对象):
{
"id": 1,
"name": "apple",
"price": "33"
}
当然,指定id为1的获取指令还可以用如下指令,但要注意,此时返回的数据是一个数组。
http://localhost:3004/fruits?id=1
[
{
"id": 1,
"name": "apple",
"price": "33"
}
]
以此类推,我们也可以通过水果名称,或者是价格来获取数据:
http://localhost:3004/fruits?name=orange
[
{
"id": 2,
"name": "orange",
"price": "8.88"
}
]
也可以指定多个条件,用&符号连接:
http://localhost:3004/fruits?name=orange&price=8.88
[
{
"id": 2,
"name": "orange",
"price": "8.88"
}
]
你甚至还可以使用对象取属性值 obj.key 的方式:
http://localhost:3004/users?name.nickname=dachui
[
{
"name": {
"username": "admin",
"nickname": "dachui"
},
"pwd": "123456"
}
]
以上看着是不是特别眼熟,不就是HTTP中GET请求方式嘛~
嗯,更好玩的还在后面
分页 Paginate
为了能演示分页效果,我们在db.json文件里的fruits里面多添加了几种水果。
{
"fruits": [
{
"id": 1,
"name": "apple1",
"price": "33"
},
{
"id": 2,
"name": "apple2",
"price": "2"
},
{
"id": 3,
"name": "apple3",
"price": "3"
},
{
"id": 4,
"name": "apple4",
"price": "4"
},
{
"id": 5,
"name": "apple5",
"price": "5"
},
{
"id": 6,
"name": "orange",
"price": "8.88"
}
],
"users": [
{
"name": {
"username":"admin",
"nickname":"dachui"
},
"pwd": "123456"
}
]
}
编辑过db.json(db.json数据有变动),都要关闭服务重新启动。(注意:不要用 CTRL + C 来停止服务,因为这种方式会导致 node.js 依旧霸占着3004端口,导致下一次启动失败。简单粗暴关闭窗口即可! —— 个人window系统,其他系统可能没有这样的烦恼。)
分页采用 _page
来设置页码, _limit
来控制每页显示条数。如果没有指定 _limit
,默认每页显示10条。
http://localhost:3004/fruits?_page=2&_limit=2
[
{
"id": 3,
"name": "apple3",
"price": "3"
},
{
"id": 4,
"name": "apple4",
"price": "4"
}
]
排序 Sort
排序采用 _sort
来指定要排序的字段, _order
来指定排序是正排序还是逆排序(asc | desc ,默认是asc)。
http://localhost:3004/fruits?_sort=id&_order=desc
[
{
"id": 6,
"name": "orange",
"price": "8.88"
},
{
"id": 5,
"name": "apple5",
"price": "5"
},
{
"id": 4,
"name": "apple4",
"price": "4"
},
{
"id": 3,
"name": "apple3",
"price": "3"
},
{
"id": 2,
"name": "apple2",
"price": "2"
},
{
"id": 1,
"name": "apple1",
"price": "33"
}
]
也可以指定多个字段排序,一般是按照id进行排序后,相同id的再跟进name排序(此块没有具体造数据格式,猜测如此):
http://localhost:3004/fruits?_sort=id,name&_order=desc,asc
取局部数据 Slice
slice的方式,和 Array.slice() 方法类似。采用 _start
来指定开始位置, _end
来指定结束位置、或者是用_limit
来指定从开始位置起往后取几个数据。
http://localhost:3004/fruits?_start=2&_end=4
[
{
"id": 3,
"name": "apple3",
"price": "3"
},
{
"id": 4,
"name": "apple4",
"price": "4"
}
]
http://localhost:3004/fruits?_start=2&_limit=4
[
{
"id": 3,
"name": "apple3",
"price": "3"
},
{
"id": 4,
"name": "apple4",
"price": "4"
},
{
"id": 5,
"name": "apple5",
"price": "5"
},
{
"id": 6,
"name": "orange",
"price": "8.88"
}
]
取符合某个范围 Operators
(1)采用 _gte
_lte
来设置一个取值范围(range):
http://localhost:3004/fruits?id_gte=4&id_lte=6
[
{
"id": 4,
"name": "apple4",
"price": "4"
},
{
"id": 5,
"name": "apple5",
"price": "5"
},
{
"id": 6,
"name": "orange",
"price": "8.88"
}
]
(2)采用_ne
来设置不包含某个值:
http://localhost:3004/fruits?id_ne=1
[
{
"id": 2,
"name": "apple2",
"price": "2"
},
{
"id": 3,
"name": "apple3",
"price": "3"
},
{
"id": 4,
"name": "apple4",
"price": "4"
},
{
"id": 5,
"name": "apple5",
"price": "5"
},
{
"id": 6,
"name": "orange",
"price": "8.88"
}
]
(3)采用_like
来设置匹配某个字符串(或正则表达式):
http://localhost:3004/fruits?name_like=apple
[
{
"id": 2,
"name": "apple2",
"price": "2"
},
{
"id": 3,
"name": "apple3",
"price": "3"
},
{
"id": 4,
"name": "apple4",
"price": "4"
},
{
"id": 5,
"name": "apple5",
"price": "5"
}
]
全文搜索 Full-text search
采用 q
来设置搜索内容:
http://localhost:3004/fruits?q=oran
[
{
"id": 6,
"name": "orange",
"price": "8.88"
}
]
关联关系 Relationships
(1)采用 _embed
来设置(创建或包含)一个子资源。
http://localhost:3004/users?_embed=personInfo
[
{
"name": {
"username": "admin",
"nickname": "dachui"
},
"pwd": "123456",
"personInfo": []
}
]
(2)采用 _expand
来设置是否包含某个父资源。(测试数据的局限性,我没太懂这条指令的意思了,之后在试试看。)
http://localhost:3004/fruits?_expand=users
[
{
"id": 1,
"name": "apple1",
"price": "33"
},
{
"id": 2,
"name": "apple2",
"price": "2"
},
{
"id": 3,
"name": "apple3",
"price": "3"
},
{
"id": 4,
"name": "apple4",
"price": "4"
},
{
"id": 5,
"name": "apple5",
"price": "5"
},
{
"id": 6,
"name": "orange",
"price": "8.88"
}
]
(3)获取嵌套资源(测试数据局限性,这条指令是虚拟的。)
http://localhost:3004/fruit/1/shops
以上主要介绍GET的功能,通过浏览器请求数据。
下一篇 上手玩一下json-server(二)操作数据篇——POST/PATCH/DELETE,我们将用ajax方式来获取/修改数据。