在进行前端应用开发时,通常需要模拟一个后端API来进行开发和测试。使用json-server
工具可以帮助我们快速地搭建一个RESTful风格的API,使用JSON格式作为数据交互的格式。json-server
可以快速创建RESTful API,支持各种常见的功能和扩展,比如查询参数、嵌套路由、自定义路由、自定义中间件等,同时还支持实时更新。在这篇文章中,我们将介绍如何使用json-server
搭建模拟的API,并使用Axios来进行数据请求和操作。
json-server入门使用
json-server
是一个基于 Node.js 的开源工具,可以帮助快速搭建一个 RESTful 风格的 API,使用 JSON 格式作为数据交互的格式。在开发前端应用时,我们常常需要模拟一个后端 API 来进行开发,这时可以使用 json-server
来快速搭建一个模拟的 API。
以下是安装 json-server
的步骤:
-
首先需要安装 Node.js 环境,可以从官网下载安装包进行安装:nodejs.org/
-
在命令行中输入以下命令安装
json-server
:npm install -g json-server
这个命令会将
json-server
安装到全局环境中,以便在任何目录下使用。 -
准备一个 JSON 文件作为模拟的数据源,例如
db.json
,可以在该文件中定义 RESTful API 的路由和数据,例如:{ "posts": [ { "id": 1, "title": "json-server", "author": "John Doe" }, { "id": 2, "title": "RESTful API", "author": "Jane Doe" } ], "comments": [ { "id": 1, "body": "some comment", "postId": 1 }, { "id": 2, "body": "some other comment", "postId": 2 } ] }
-
在命令行中进入到
db.json
所在目录,输入以下命令启动json-server
:json-server --watch db.json
这个命令会启动
json-server
,并监听db.json
文件的变化。在浏览器中访问 http://localhost:3000/posts 就可以看到posts
数据的内容了。除此之外,json-server
还支持很多高级的功能。 -
然后,可以编写以下代码来进行
GET
请求:
axios.get('http://localhost:5000/posts')
.then(response => {
console.log(response.data)
})
.catch(error => {
console.log(error)
})
这将从 http://localhost:5000/posts
获取所有帖子并将响应打印到控制台。
接下来,可以使用 POST
请求来创建新的帖子:
axios.post('http://localhost:5000/posts', {
title: '新帖子的标题',
body: '新帖子的内容'
})
.then(response => {
console.log(response.data)
})
.catch(error => {
console.log(error)
})
这将创建一条新的帖子,并将其标题和内容设置为 '新帖子的标题'
和 '新帖子的内容'
。
然后,可以使用 PUT
或patch
请求来更新现有的帖子:
// PATCH 请求示例
axios.patch('http://localhost:5000/posts/1', {
title: 'New title'
})
.then(response => {
console.log(response.data);
})
.catch(error => {
console.log(error);
});
// PUT 请求示例
axios.put('http://localhost:5000/posts/1', {
id: 1,
title: 'New title',
author: 'New author'
})
.then(response => {
console.log(response.data);
})
.catch(error => {
console.log(error);
});
这里的 axios.patch
和 axios.put
的第一个参数是要请求的 URL,第二个参数是要更新的数据。注意,在 PUT
请求中,由于是全部替换,所以需要提供整个资源的完整信息(包括未修改的部分)。而在PACTH
则是打补丁的形式局部修改,只需要提供想要局部修改的部分
最后,可以使用 DELETE
请求来删除现有的帖子:
axios.delete('http://localhost:5000/posts/1')
.then(response => {
console.log(response.data)
})
.catch(error => {
console.log(error)
})
这将删除 ID 为 1
的帖子。
json-server为什么不用跨域就能取到数据
json-server 默认支持跨域请求,会在响应头中添加如下信息:
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET,HEAD,PUT,PATCH,POST,DELETE
Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept
其中 Access-Control-Allow-Origin: *
表示允许所有域名跨域请求,也可以指定具体的域名。
如果你需要自定义跨域头信息,可以通过自定义中间件的方式来实现。例如,可以在 middlewares.js
中定义一个中间件,然后在启动 json-server 时指定该中间件:
// middlewares.js
module.exports = (req, res, next) => {
res.setHeader('Access-Control-Allow-Origin', 'http://localhost:3000');
res.setHeader('Access-Control-Allow-Methods', 'GET,POST,PUT,DELETE,OPTIONS');
res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Access-Control-Allow-Headers');
next();
};
// 启动 json-server 并指定中间件
json-server db.json --middlewares ./middlewares.js
这样,json-server 在响应请求时就会添加自定义的跨域头信息。
json-server扁平化模拟数据间的关联
可以使用json-server
中的routes
功能来模拟数据之间的关联。假设posts
和comments
是两个独立的资源,且comments
资源需要关联到posts
资源的id
上,可以使用以下配置来实现:
// db.json
{
"posts": [
{
"id": 1,
"title": "Post 1"
},
{
"id": 2,
"title": "Post 2"
}
],
"comments": [
{
"id": 1,
"postId": 1,
"body": "Comment 1"
},
{
"id": 2,
"postId": 1,
"body": "Comment 2"
},
{
"id": 3,
"postId": 2,
"body": "Comment 3"
}
]
}
然后,使用以下命令启动json-server
并配置路由:
json-server db.json --routes routes.json
其中,routes.json
文件内容如下:
{
"/posts/:id/comments": "/comments?postId=:id"
}
这样就可以通过/posts/:id/comments
接口获取指定id
的post
下的所有comments
数据,例如:
http://localhost:3000/posts/1/comments
这将返回以下数据:
[
{
"id": 1,
"postId": 1,
"body": "Comment 1"
},
{
"id": 2,
"postId": 1,
"body": "Comment 2"
}
]
注意,这里并没有使用嵌套来实现关联,而是通过路由配置来模拟关联。这种方式的好处是可以保持数据的扁平化,避免了深度嵌套的问题。
_embed
、 __expand
获取关联数据
可以使用 _embed
参数来在一个请求中同时获取到相关联的数据。在上述的示例中,如果想要在获取 posts
时同时获取关联的 comments
数据,可以将请求改为:
GET http://localhost:5000/posts?_embed=comments
这样,返回结果中每个 post
对象都会带有一个 comments
属性,属性值为一个包含关联评论对象的数组。例如:
[
{
"id": 1,
"title": "Post 1",
"comments": [
{
"id": 1,
"body": "Comment 1 on post 1",
"postId": 1
},
{
"id": 2,
"body": "Comment 2 on post 1",
"postId": 1
}
]
},
{
"id": 2,
"title": "Post 2",
"comments": [
{
"id": 3,
"body": "Comment 1 on post 2",
"postId": 2
}
]
}
]
说完向下关联,来看看向上关联,还是以上一个示例为例,假设我们想要获取所有评论以及它们所对应的帖子的详细信息,我们可以使用 _expand
参数来展开关联的帖子信息。
例如,我们可以发送如下 GET 请求:
GET /comments?_expand=post
这将返回所有评论以及它们所对应的帖子的详细信息,如下所示:
{
"comments": [
{
"id": 1,
"postId": 1,
"body": "Comment 1",
"post": {
"id": 1,
"title": "Post 1"
}
},
{
"id": 2,
"postId": 1,
"body": "Comment 2",
"post": {
"id": 1,
"title": "Post 1"
}
},
{
"id": 3,
"postId": 2,
"body": "Comment 3",
"post": {
"id": 2,
"title": "Post 2"
}
}
]
}
注意到每个评论对象中都包含了对应的帖子信息,这样可以避免在前端再次发送请求获取帖子信息,提高了数据访问效率。
json-server有哪些好用功能
- 快速生成 RESTful API:使用 json-server 可以快速地创建 RESTful API,并且不需要写任何后端代码。只需要在 JSON 文件中定义数据,然后启动 json-server,就可以使用 RESTful API 对数据进行 CRUD 操作。
- 支持各种 HTTP 动词:json-server 支持常见的 HTTP 动词,如 GET、POST、PUT、DELETE 等,可以方便地对数据进行操作。
- 支持查询参数:json-server 支持查询参数,如过滤、排序、分页等,可以通过 URL 参数对数据进行筛选和排序。
- 支持嵌套路由:json-server 支持嵌套路由,可以通过嵌套的 JSON 文件结构来实现路由的嵌套。
- 支持自定义路由:json-server 支持自定义路由,可以通过配置 JSON 文件来自定义路由,以满足特定的需求。
- 支持自定义中间件:json-server 支持自定义中间件,可以通过编写 JavaScript 函数来扩展 json-server 的功能。
- 支持实时更新:json-server 支持实时更新,可以在数据文件发生变化时自动重新加载数据,从而使得开发过程更加流畅。
总的来说,json-server 是一个非常方便的工具,可以帮助开发人员快速地创建 RESTful API,并且支持各种常见的功能和扩展。