作用:
前端用来写接口的工具,无需等待后端接口,方便前端快速开发
使用背景:
项目中经常会遇到前端页面写得差不多了,需要后端有接口有数据才能继续进行前端开发,这样太浪费时间,通常我们会自己在页面中写假数据,保证页面的正常开发,但并没有真正的调接口,功能是没有的,得等后端接口,后面有接口了还得回过头来把假数据删了,掉接口调页面,很麻烦,如果我们有接口,就可以一气呵成,避免了删假数据的麻烦,同时功能也有了,等后盾接口有了,我们替换一下url地址就行,不用在回过头来看前端逻辑,json-server就是用来生成测试接口的工具,只需指定一个 json
文件作为 api
的数据源即可,并且支持跨域,使用起来非常方便,基本上有手就行
json-server的github地址:
具体使用请看官网
使用步骤:
1. 安装 Node.js 环境即可(这个前端都有安装),安装 JSON 服务器
npm install -g json-server
2. 创建一个db.json
包含一些数据的文件
3. 启动 json-server
接口服务器 json-server --watch db.json
4. 浏览器访问 http://localhost:3000/posts/1,你会得到
{ "id": 1, "title": "json-server", "author": "typicode" }
如果您发出 POST、PUT、PATCH 或 DELETE 请求,更改将自动安全地保存到 db.json
文件中。注意 Id 值是不可变的
路由形式一:
GET /posts
GET /posts/1
POST /posts
PUT /posts/1
PATCH /posts/1
DELETE /posts/1
筛选:
GET /posts?title=json-server&author=typicode
GET /posts?id=1&id=2
GET /comments?author.name=typicode
分页:
使用_page
和可选地_limit
对返回的数据进行分页。默认返回10项
GET /posts?_page=7
GET /posts?_page=7&_limit=20
排序:
添加
_sort
和_order
(默认升序)GET /posts?_sort=views&_order=asc
GET /posts/1/comments?_sort=votes&_order=asc
切片(分页):
GET /posts?_start=20&_end=30
GET /posts/1/comments?_start=20&_end=30
GET /posts/1/comments?_start=20&_limit=10
全文搜索:
添加
q
GET /posts?q=internet
基本使用不足之处:
至此,基本增删改查分页已经可以,但是还是不足以整合到项目中,因为这样简单的使用虽然可以,但是有以下几个缺点
1.默认的没有返回,code,data,msg,
2.目前这样所有的测试数据只能写在一个json文件中,不便于模块化管理
3.我们每次的增删改查的数据都会写入这个json文件中,测试多了会导致这个json文件越来越大
4.json文件不便于我们书写注释
改进版本:
1. 因为json-server时基本express框架的,所以,我们可以自定义输入内容,从而返回code,data,msg,
2. 我们不使用json文件提供默认数据,而是模块划分,使用js对象的形式提供默认数据,便于注释和模块化管理
3. 使用内存数据库,这样当我们在增删改查的时候,就不会把数据存入json文件中,而是存在内存中,当json-server服务器关闭后,内存数据就消失了,就不会导致json文件中数据会变大
基本代码如下:
可直接使用,下载nodemon,建议全局安装,
npm i -g nodemon
在server.js目录下运行:
nodemon server.js
// server.js
/**
* 使用内存数据库,数据不会保存在本地json文件中
*/
/**
* 读取db文件夹下的数据作为数据库数据
* @returns 数据库数据 dbData
*/
function readData () {
const fs = require('fs')
return new Promise((resolve) => {
fs.readdir('./db', (err, files) => {
if (err) return
const dbData = {}
files.forEach(v => {
const x = require('./db' + '\\' + v)
Object.keys(x).forEach(item => (dbData[item] = x[item]))
})
resolve(dbData)
})
})
}
/**
* 开启json-server服务器
* @param {*} dbData 数据库数据
*/
function startServer (dbData) {
const jsonServer = require('json-server')
const server = jsonServer.create()
const middlewares = jsonServer.defaults()
const router = jsonServer.router(dbData)
server.use(middlewares)
server.use(router)
router.render = (req, res) => {
if (req.method === 'GET') {
const pathname = req._parsedUrl.pathname
const dbName = pathname.split('/').filter(v => v!=='')[0]
// console.log(router.db.__wrapped__);
res.jsonp({
data: {
list: res.locals.data,
// 获取数据库下对应的数据数量
total: router.db.__wrapped__[dbName]?.length || 0
},
msg: 'success',
code: '0000'
})
} else {
res.jsonp({
data: res.locals.data,
msg: 'success',
code: '0000'
})
}
}
server.listen(6600, () => {
console.log('http://127.0.0.1:6600');
})
}
(async () => {
const dbData = await readData()
startServer(dbData)
})()
目录结构