![cover](https://img-blog.csdnimg.cn/ddd6c72b64d64d35ad78dc3316c919d5.jpg)
『前端必备』本地数据接口 —— json-server 从入门到膨胀
原文出处:『前端必备』本地数据接口 —— json-server 从入门到膨胀前言Ajax 是前端必学的一个知识点,但刚接触 Ajax 的同学可能会因为没接口测试而烦恼。本文 入门篇 会花你10分钟解决 没接口测试 这个烦恼,而且不需要你具备后端知识。如果不想自己在本地搭环境,还可以使用 《前端需要的免费在线api接口》 里推荐的几个线上接口平台,里面包括常用的 json 结构数据和图片。虽然有线
前言
Ajax
是前端必学的一个知识点,但刚接触 Ajax
的同学可能会因为没接口测试而烦恼。
本文 入门篇 会花你10分钟解决 没接口测试 这个烦恼,而且不需要你具备后端知识。
如果不想自己在本地搭环境,还可以使用 《前端需要的免费在线api接口》 里推荐的几个线上接口平台,里面包括常用的 json
结构数据和图片。
虽然有线上的免费接口可以测试,但需要自定义接口和数据的时候,还是本地模拟数据比较适合前端开发者。
本文分 入门篇 和 进阶篇。再往下滑一点就能看到全文目录。
入门篇: 5分钟内带你实现 本地环境搭建 和 增删改查 操作,满足入门测试使用。
进阶篇: 主要讲解常用的 查询操作,除此之外还包括 常规配置、静态资源配置 等知识点。这部分有点长,建议收藏。
本文约定
- 本文主要面向的读者是 前端小白,几乎不会涉及到后端知识,所以并不打算讲解
json-server 中间件
的内容。 - 本文讲到的所有知识点都会提供对应的代码展示(会比官方文档详细点)。
- 本文使用
postman
测试,希望能照顾到使用不同工具库做数据请求的读者(我知道还有只懂jQuery
的开发者)。 - 特殊情况会使用
axios
配合演示。
点赞 + 收藏 = 学会了
目录
入门
json-server简介
Get a full fake REST API with zero coding in less than 30 seconds (seriously)
引用了官方的一句话,大概意思是30秒就能获得一套完整的模拟 REST API 接口。
使用 json-server
需要遵守一定的规范。
- 数据查询要使用
GET
。 - 新增数据要使用
POST
。 - 删除数据要使用
DELETE
。 - 修改数据使用
PUT
和PATCH
。
其他啰嗦的介绍可以打开上面提供的网址看看。
30秒起步
30秒起步分 4 步完成:
node
环境安装- 安装
json-server
- 创建数据库(其实就是一个
json
文件) - 启动服务
1. node 环境安装
json-server
需要通过 npm
下载,npm
依赖在 node
中。
node
常见的安装方法有2种。第一种是官方下载,第二种是使用 nvm
下载。自己选一种就行。
node 官网,点击进入主页下载,下载完狂按“下一步”和“完成”就行了。
注意: node
版本一定要 12
以上。不然会报以下错误:
json-server requires at least version 12 of Node, please upgrade
2. 安装 json-server
可以全局安装,也可以在某项目里安装。这里建议全局安装,因为以后你可能会对 json-server
产生依赖。
全局安装方式:
npm install -g json-server
3. 创建数据库
在你本机创建一个文件夹,然后新建一个 json
文件,再填入数据即可。
建议文件名不要出现中文。
例:
创建 json-server-demo
文件夹,在 json-server-demo
里创建 db.json
文件(这些文件夹和文件名都可以自由命名)。
db.json
文件录入以下数据(数据来自 json-server
官方文档,你也可以使用自己的数据)
{
"posts": [
{
"id": 1,
"title": "json-server",
"author": "typicode"
}
],
"comments": [
{
"id": 1,
"body": "some comment",
"postId": 1
}
],
"profile": {
"name": "typicode"
}
}
4. 启动服务
进入 json-server-demo
目录,打开终端输入以下命令即可
json-server --watch db.json
首页和三个接口都可以直接在浏览器访问,自己打开试试吧。
搞掂!
查(get)
json-server
查询数据需要使用 GET
方法。
入门篇 只写一种查询方法,其他查询操作请往下滑,看 进阶篇。
上一小节创建了3个接口,我们可以直接在浏览器、postman或者自己写JS代码获取数据。
http://localhost:3000/posts
http://localhost:3000/comments
和 http://localhost:3000/profile
两个接口可以自己尝试,这里不再啰嗦。
增(post)
json-server
新增数据需要使用 POST
方法。
例:给
posts
添加一条新的数据。
http://localhost:3000/posts
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BSVFT5qg-1639966549799)(03.png)]
这里使用 POSt
方法向 /posts
接口传输数据,/posts
原本的数据结构是包含 id、title、author
三个字段,id
默认是自增主键,不传的话会默认增加。
此时打开 db.json
文件看看,可以发现 posts
里多了一条数据。
需要注意的是:
json-server
默认情况下并不会限制你上传的数据格式和类型,所以需要你严格遵循自己设计的数据格式来添加和修改。
删(delete)
json-server
删除数据需要使用 DELETE
方法。
删除的公式是:
http://localhost:3000/{接口名}/{id}
比如现在要删除刚刚上传的那条数据
{
"title": "leihou",
"author": "雷猴",
"id": 2
}
可以看到刚刚上传的那条数据的 id
为 2
http://localhost:3000/posts/2
此时打开 db.json
就会发现刚刚删除的那条数据已经没了。
需要注意的是: 删除成功
Status
会返回200
;如果删除的数据不存在会返回404
。
我用 axios
模拟了一下。
删除成功返回的结果:
删除失败返回的结果:
改(put 和 patch)
修改数据分为2个方法:
put
:覆盖patch
:更新
公式如下所示:
http://localhost:3000/posts/{id}
覆盖(put)
例:把
id
为1
的数据改成{ "title": "leihou", "author": "雷猴" }
此时打开 db.json
就可以看到 id
为 1
的数据已经发生变化。
注意:原本的数据包含
title
和author
,使用put
时必须把这两个字段都写上,不然会删掉没传的字段。这就是 “覆盖” 的意思。
例如:
此时查看 db.json
会发现数据被覆盖了
更新(patch)
先还原一下数据,改成如下图所示:
此时有 title
和 author
字段。
例:使用 patch
方法把 id
为 1
的数据 title
字段的值更改成 hello
。
打开 db.json
文件查看一下,会发现只改了 id
为 1
的 title
值,并没有删掉 author
这个字段的数据。
进阶
启动参数
我们之前使用 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 0.0.0.0 db.json
这里设置了 0.0.0.0
,之后通过本机 IP
来访问即可。同一个局域网内的其他设备也可以通过这个地址来访问。
查询的常用操作
查询是日常项目中接触最多的操作,所以查询是重点。
普通查询
用 30秒起步 的那份数据。
查询
/posts
所有数据
http://0.0.0.0: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
为参考字段进行升序排列返回给客户端。
http://localhost:3000/comments?_sort=id
或
http://localhost:3000/comments?_sort=id&_order=asc
返回的结果就会以 id
为参考字段升序排好。
普通升序排列的话,_order=asc
可以不传。只需指定 参考字段 ( _sort
) 即可。
降序
降序必须填好
_order=desc
。
http://localhost:3000/comments?_sort=id&_order=desc
多字段排序
这次的需求是:
-
首先按
postId
升序排列 -
在
1
的基础上再对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
需求:查询
comments
接口id
小于等于4
的数据
http://localhost:3000/comments?id_lte=4
联合一起使用
需求:查询
comments
接口id
大于等于4
且 小于等于6
的数据
http://localhost:3000/comments?id_gte=4&id_lte=6
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0ihFiJnl-1639966549808)(27.png)]
不等于 _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://jsonplaceholder.typicode.com/db
如果本文能给您带来帮助,请帮我 点个赞 呗~
更多推荐
所有评论(0)