
『前端必备』本地数据接口—json-server 详细介绍(进阶篇)
目录
前言
Ajax 是前端必学的一个知识点,但刚接触 Ajax 的同学可能会因为没接口测试而烦恼。
本文是 接着上一篇 用5分钟带你实现测试数据的 增删改查 操作,满足入门测试使用,解决 没接口测试 这个烦恼,而且不需要你具备后端知识。
启动参数
我们之前使用 json-server --watch db.json 这条命令启动了接口项目
json-server是服务启动的命令
--watch是参数
db.json是目标文件
使用下面这条命令可以 查看配置项:
json-server --help
# 或使用简写方式
json-server -h
|
参数 |
简写 |
说明 |
|---|---|---|
|
--config |
-c |
指定配置文件 |
|
--port |
-p |
端口号 |
|
--host |
-H |
主机地址 |
|
--watch |
-w |
监听文件 |
|
--routes |
-r |
指定路由文件 |
|
--middlewares |
-m |
指定中间件 |
|
--static |
-s |
设置静态文件 |
|
--read-only |
--ro |
只读 |
|
--no-cors |
--nc |
禁用跨源资源共享 |
|
--no-gzip |
--ng |
禁止GZIP |
|
--snapshots |
-S |
设置快照目录 |
|
--delay |
-d |
设置反馈延时(ms) |
|
--id |
-i |
设置数据的id属性(e.g. _id) |
|
--foreignKeySuffix |
--fks |
设置外键后缀(如post_id中的_id) |
|
--quiet |
-q |
禁止输出日志消息 |
|
--help |
-h |
显示帮助信息 |
|
--version |
-v |
显示版本号 |
配置
使用 json-server --help 可以查看到所有配置项。
端口
使用 -p 或者 --port 配置端口号,例如自定义配置 6666 端口
json-server -p 6666 db.json
启动后若出现以下内容则表示启动成功
\{^_^}/ hi!
Loading db.json
Done
Resources
http://localhost:6666/posts
http://localhost:6666/comments
http://localhost:6666/profile
Home
http://localhost:6666
主机地址
json-server --host 172.0.0.0 db.json
这里设置了 172.0.0.0 ,之后通过本机 IP 来访问即可。同一个局域网内的其他设备也可以通过这个地址来访问。
查询的常用操作
普通查询
在db.json 文件中录入以下数据
{
"posts": [
{
"id": 1,
"title": "json-server",
"author": "typicode"
}
],
"comments": [
{
"id": 1,
"body": "some comment",
"postId": 1
}
],
"profile": {
"name": "typicode"
}
}
查询
/posts所有数据
http://localhost:3000/posts
查询
/comments所有数据
http://localhost:3000/comments
查询
/profile所有数据
http://localhost:3000/profile
id查询
将 db.json 的内容修改一下
{
"posts": [
{
"id": 1,
"title": "文章111",
"author": "张三"
},
{
"id": 2,
"title": "文章222",
"author": "李四"
}
]
}
此时只有 posts 接口,里面有2条数据,id 分别为 1 和 2。
查询的公式是:
http://localhost:3000/posts/{id}
查询
id为2的数据
http://localhost:3000/posts/2

条件查询
准备以下数据
{
"posts": [
{
"id": 1,
"title": "文章111",
"author": "张三"
},
{
"id": 2,
"title": "文章222",
"author": "李四"
},
{
"id": 3,
"title": "文章333",
"author": "张三"
}
]
}
可以看到里面有 2条张三 的数据,1条李四 的数据。
单一条件查询
查找 author 为 张三 的所有数据。
查询
author是张三的数据
http://localhost:3000/posts?author=张三

在 http://localhost:3000/posts 后面加一个 ? ,然后写上需要筛选条件的即可。
多条件查询(且)
上面的数据,有2条张三
这次要筛选的是
author = 张三且title = 文章333的数据
http://localhost:3000/posts?author=张三&title=文章333

符合条件筛选的时候,使用 & 号添加条件。
多条件查询(或)
这次要筛选的是
title = 222和title = 333这两条数据出来。
http://localhost:3000/posts?title=文章222&title=文章333

重复使用 title ,会把符合条件的都筛查出来。
当然,我们还可以使用 模糊查询 来达到类似的效果,下面会讲到。
深度属性查询
准备另一份数据,数据内容如下:
{
"posts": [
{
"id": 1,
"title": "文章111",
"authorInfo": {
"name": "张三",
"age": 20
}
},
{
"id": 2,
"title": "文章222",
"authorInfo": {
"name": "李四",
"age": 24
}
}
]
}
可以看到 authorInfo 里面还有子属性。
查询
authorInfo.name = 张三的数据
http://localhost:3000/posts?authorInfo.name=张三

这里需要使用 . 的方式来访问子级数据,有点像 js 用点语法访问对象属性。
分页查询
使用 _page 和 _limit(可选) 对数据进行分页。需要注意,_page 和 _limit 前面都要有下划线。
_page:页码_limit:每页的数据量
修改 db.json 里的数据方便测试分页功能,如下所示
{
"comments": [
{ "id": 1, "body": "some comment 1", "postId": 1 },
{ "id": 2, "body": "some comment 2", "postId": 1 },
{ "id": 3, "body": "some comment 3", "postId": 2 },
{ "id": 4, "body": "some comment 4", "postId": 3 },
{ "id": 5, "body": "some comment 5", "postId": 1 },
{ "id": 6, "body": "some comment 6", "postId": 3 },
{ "id": 7, "body": "some comment 7", "postId": 3 },
{ "id": 8, "body": "some comment 8", "postId": 1 },
{ "id": 9, "body": "some comment 9", "postId": 2 },
{ "id": 10, "body": "some comment 10", "postId": 2 },
{ "id": 11, "body": "some comment 11", "postId": 3 },
{ "id": 12, "body": "some comment 11", "postId": 1 }
]
}
准备了12条数据。
若此时需要获取去第2页的数据,并且每页3条:
http://localhost:3000/comments?_page=2&_limit=3

除了要返回的数据外,还会在 Headers 里返回 总数;第一个、前一个、下一个、最后一个的链接。我用 axios 发个请求演示一下。
axios.get('http://localhost:3000/comments', {
params: {
_page: 2,
_limit: 3
}
})
.then(res => {
console.log(res)
})
.catch(err => {
console.error(err)
})
返回结果如下所示

x-total-count 存放总数。
link 字段里存放的是 第一个、前一个、下一个、最后一个 的链接地址
"
<http://localhost:3000/comments?_page=1&_limit=3>; rel=\"first\", <http://localhost:3000/comments?_page=1&_limit=3>; rel=\"prev\", <http://localhost:3000/comments?_page=3&_limit=3>; rel=\"next\", <http://localhost:3000/comments?_page=4&_limit=3>; rel=\"last\"
"
排序查询
需要添加 **排序的标记 (
_sort)**,然后设置 **排序规则 (_order)**
排序规则:
- 升序 (
asc)- 降序 (
desc)
http://localhost:3000/{接口名}?_sort=要排序的字段名&_order=排序规则
以这份数据为例:
{
"comments": [
{ "id": 11, "body": "some comment 1", "postId": 1 },
{ "id": 2, "body": "some comment 2", "postId": 1 },
{ "id": 3, "body": "some comment 3", "postId": 2 },
{ "id": 10, "body": "some comment 4", "postId": 3 },
{ "id": 7, "body": "some comment 5", "postId": 1 },
{ "id": 6, "body": "some comment 6", "postId": 3 },
{ "id": 5, "body": "some comment 7", "postId": 3 },
{ "id": 8, "body": "some comment 8", "postId": 1 },
{ "id": 9, "body": "some comment 9", "postId": 2 },
{ "id": 4, "body": "some comment 10", "postId": 2 },
{ "id": 1, "body": "some comment 11", "postId": 3 },
{ "id": 12, "body": "some comment 11", "postId": 1 }
]
}
id 的排序是乱的,如果使用普通的方式请求回来的数据是原模原样返回的。
升序
以
id为参考字段进行升序排列返回给客户端。
普通升序排列的话,
_order=asc可以不传。只需指定 参考字段 (_sort) 即可
http://localhost:3000/comments?_sort=id
或
http://localhost:3000/comments?_sort=id&_order=asc

返回的结果就会以 id 为参考字段升序排好。
降序
降序必须填好
_order=desc
http://localhost:3000/comments?_sort=id&_order=desc

多字段排序
这次的需求是:
- 首先按
postId升序排列- 在
postId升序 的基础上再对id进行倒序排列
多个字段用
,分格。
http://localhost:3000/comments?_sort=postId,id&_order=asc,desc
返回结果:
{
"comments": [
{ "id": 12, "body": "some comment 11", "postId": 1 },
{ "id": 11, "body": "some comment 1", "postId": 1 },
{ "id": 8, "body": "some comment 8", "postId": 1 },
{ "id": 7, "body": "some comment 5", "postId": 1 },
{ "id": 2, "body": "some comment 2", "postId": 1 },
{ "id": 9, "body": "some comment 9", "postId": 2 },
{ "id": 4, "body": "some comment 10", "postId": 2 },
{ "id": 3, "body": "some comment 3", "postId": 2 },
{ "id": 10, "body": "some comment 4", "postId": 3 },
{ "id": 6, "body": "some comment 6", "postId": 3 },
{ "id": 5, "body": "some comment 7", "postId": 3 },
{ "id": 1, "body": "some comment 11", "postId": 3 }
]
}
切片查询
切片的意思是指定 头 和 尾 ;也可以指定 头 和 片段长度 。
用到的关键字有:
_start:开始位置(下标,从0开始)_end:结束位置_limit:片段长度
总数 会放在 headers 里。
以这份数据为例
{
"comments": [
{ "id": 1, "body": "some comment 1", "postId": 1 },
{ "id": 2, "body": "some comment 2", "postId": 1 },
{ "id": 3, "body": "some comment 3", "postId": 2 },
{ "id": 4, "body": "some comment 4", "postId": 3 },
{ "id": 5, "body": "some comment 5", "postId": 1 },
{ "id": 6, "body": "some comment 6", "postId": 3 },
{ "id": 7, "body": "some comment 7", "postId": 3 },
{ "id": 8, "body": "some comment 8", "postId": 1 },
{ "id": 9, "body": "some comment 9", "postId": 2 },
{ "id": 10, "body": "some comment 10", "postId": 2 },
{ "id": 11, "body": "some comment 11", "postId": 3 },
{ "id": 12, "body": "some comment 11", "postId": 1 }
]
}
需求:返回下标从
2-6的数据
使用 _start 和 _end 的方式
http://localhost:3000/comments?_start=2&_end=6
使用 _start 和 _limit 的方式
http://localhost:3000/comments?_start=2&_limit=4

范围查询
范围查询包括 大于等于、小于等于、不等于 三种情况。
大于等于 _get
大于等于 使用的关键字是
_get。注意,前面有个下划线的。
需求:查询
comments接口id大于等于4的数据
http://localhost:3000/comments?id_gte=4

小于等于 _lte
小于等于 使用的关键字是
_lte。注意,前面有个下划线的。
需求:查询
comments接口id小于等于4的数据
http://localhost:3000/comments?id_lte=4

联合一起使用
需求:查询
comments接口id大于等于4且 小于等于6的数据
http://localhost:3000/comments?id_gte=4&id_lte=6

不等于 _ne
需求:查询
comments接口id不等于2的数据
http://localhost:3000/comments?id_ne=2

模糊查询
模糊查询的关键字是 _like。
需求:查询
comments接口body包含1的数据

全文查询
全文查询的关键字是 q
准备以下数据比较好演示
{
"authors": [
{ "id": 1, "name": "zhangsan", "age": 18},
{ "id": 2, "name": "lisi", "age": 21},
{ "id": 3, "name": "wangwu", "age": 24}
]
}
查询所有字段中包含
2的数据出来
http://localhost:3000/authors?q=2

因为 id 为 3 的那条数据里 age 是 24 ,也算是包含了 2 。
外键关联查询
外键查询需要 2个接口 关联查询。
准备以下数据方便演示
{
"posts": [
{ "id": 1, "title": "文章111", "author": "张三" },
{ "id": 2, "title": "文章222", "author": "李四" }
],
"comments": [
{ "id": 1, "body": "some comment 1", "postId": 1 },
{ "id": 2, "body": "some comment 2", "postId": 1 },
{ "id": 3, "body": "some comment 3", "postId": 2 }
]
}
posts 里有2条数据。
comments 里有3条数据,其中每条数据都有一个 postId,是对应 posts 每条数据的 id。
需求:查询
posts里id为1的所有comments内容
http://localhost:3000/posts/1/comments

关系拼装
关系拼装可以把关联的2个接口的数据拼接起来并返回。
其中有2种查询关系:
- 包含子资源
_embed- 包含父资源
_expand
准备以下数据方便演示
{
"posts": [
{ "id": 1, "title": "文章111", "author": "张三" },
{ "id": 2, "title": "文章222", "author": "李四" }
],
"comments": [
{ "id": 1, "body": "some comment 1", "postId": 1 },
{ "id": 2, "body": "some comment 2", "postId": 1 },
{ "id": 3, "body": "some comment 3", "postId": 2 }
]
}
包含子资源 _embed
http://localhost:3000/posts?_embed=comments

还可以拼接多个条件。
需求:在
comments里,把posts里id为2的数据找出来并拼接起来
http://localhost:3000/posts/2?_embed=comments

包含父资源 _expand
http://localhost:3000/comments?_expand=post

配置路由
有时候我们的 api地址 可能不像上面所有案例中那么简单,此时就可以使用 自定义路由 的方法来模拟。
比如模拟下面这个接口:
http://localhost:3000/api/users/1
实现的步骤如下所示:
- 创建
routes.json文件(文件名自定义) - 启动服务时使用
--routes参数
1、创建 routes.json ,并输入以下内容。
{
"/api/*": "/$1"
}
2、启动服务
json-server db.json --routes routes.json
3、访问
http://localhost:3000/api/posts
静态资源
静态资源包含 html 、css 、js 、图片、视频等资源。
配置
配置方式分2种:
- 默认配置
- 指定资源位置
默认配置
需要在根目录下创建 public 文件夹,里面放入 html 等文件。

然后在浏览器访问一下 http://localhost:3000/
你也可以加入自己的 css 和 js 进行设计交互。
指定资源位置
json-server配资静态资源的默认方式是在根目录下创建public文件夹,然后里面放入静态资源。
但如果你不想使用 public 作为静态资源的文件夹,也可以自己另起一个名字,然后在启动环境时使用 --static 来指定目标目录就行了。
比如我创建了一个 some-other-dir 作为静态资源的目录,使用以下命令指定以下即可。
json-server db.json --static ./some-other-dir
多媒体资源
除了放 html 、css 和 js 资源外,还可以放图片和视频。
我以图片为例,我在 public 目录下添加一个图片

直接在 http://localhost:3000/ 后面跟着 图片文件名 即可。

其他
生成动态数据
如果我们要模拟100条数据,甚至更多的话,创建 json 文件然后一条一条录入的方式真的很不合时。
此时我们可以使用 js 通过循环的方式来实现数据创建。
1、首先在根目录下创建一个 db.js 的文件。
2、输入一下内容
module.exports = () => {
const data = { users: [] }
// 创建 100 个 users
for (let i = 0; i < 100; i++) {
data.users.push({ id: i, name: `user${i}` })
}
return data
}
3、运行 js 文件
json-server db.js
4、查询一下
http://localhost:3000/users
100条数据就直接生成了。

需要什么字段可以自己在 js 文件里配置。
查询整个数据库
访问以下地址可以获得整个数据库的数据。
http://localhost:3000/db
远程模式
如果想使用互联网上的数据,也可以直接运行 json-server 然后加上远端的地址即可。
$ json-server http://example.com/file.json
$ json-server http://jsonplaceholder.typicode.com/db
添加自定义路由
创建一个routes.json文件。注意每条路线都以/.
{
"/api/*": "/$1",
"/:resource/:id/show": "/:resource/:id",
"/posts/:category": "/posts?category=:category",
"/articles\\?id=:id": "/posts/:id"
}
使用--routes选项启动 JSON 服务器。
json-server db.json --routes routes.json
现在就可以使用其他路线访问资源。
/api/posts # → /posts
/api/posts/1 # → /posts/1
/posts/1/show # → /posts/1
/posts/javascript # → /posts?category=javascript
/articles?id=1 # → /posts/1
更多推荐




所有评论(0)