1 前言
很久没有写文章了,不管什么原因,总觉得心里还是觉得有点焦虑,不看看书写点东西就有莫名的焦虑,仿佛只有忙起来才能忘记焦虑。虽然我也知道更重要的是思考方向,但是就像走路,不出发随着时间的流逝,总觉得有种焦虑感,总觉得一直走在路上,才有踏实的充实感,不知道你们是不是这种感觉,还是只是我的个人感觉。
2 不用写代码的服务器
这篇文章不是什么高深的底层知识,只是介绍个工具。原因我在写后端代码的时候,代码内部需要调用个Restful服务,而这个服务是其他同事开发的,没有开发好。所以我想找个模拟器,类似mock,模拟服务器端进行调试。
很久前有见过一款同事开发的那种模拟tcp的服务器,挺好用的界面版本,可以配置对接收到不同的消息,返回不同的结果,挺好的,找不到了。自己也懒得去写了就在github上找了下,发现一款好用的模拟Restful服务器,尝试下,非常好用,还支持定制。
3 Json-Server
json-server 是用js开发的,作为后端开发者可能对js开发的应用有点排斥,不过尝试了就知道,其实也挺好用,现在我甚至觉得用nodejs开发,其实是件很爽的事情,代码写的像python,简单库还挺丰富的。
3.1 原理
json-server的原理比较简单,后端提供个json文件,然后利用lowdb(一个将json文件当数据库的开源库,参考:https://github.com/typicode/lowdb)作为后端的数据存储服务器做的服务。 举个lowdb的例子:
// Edit db.json content using plain JavaScript
db.data.posts.push({ id: 1, title: 'lowdb is awesome' })
// Save to file
db.write()
// db.json
{
"posts": [
{ "id": 1, "title": "lowdb is awesome" }
]
}
在github上有19.8k个star,确实是思路清奇的作品啊。 json-server就是利用lowdb作为后端数据存储服务,然后处理下Restful数据,用图表示如下: 图中的Httpie是python写的类似于curl的工具,可以发起http的请求。
3.2 安装和配置
安装方法比较简单,需要通过npm安装(作为java开发人员可以理解为类似maven工具,管理js的包,且可以下载安装依赖包),npm安装的地址为:https://nodejs.org/en
安装好npm就可以安装json-server了,如下命令:
npm install -g json-server
# verify the installation was successful
json-server -v
配置json-server其实比较简单,就是新建个配置文件,上面说了json-server利用lowdb作为后端存储,和我们平时开发利用mysql存储数据没有多少的区别。 所谓的配置就是新建个配置文件,用网上的例子如下:
{
"wines": [
{ "id": 1, "product": "SOMMELIER SELECT",
"desc": "Old vine Cabernet Sauvignon", "price": 159.99 },
{ "id": 2, "product": "MASTER VINTNER",
"desc": "Pinot Noir captures luscious aromas", "price": 89.99 },
{ "id": 3, "product": "WINEMAKER'S RESERVE",
"desc": "Merlot featuring complex flavors of cherry", "price": 84.99 },
{ "id": 4, "product": "ITALIAN SANGIOVESE",
"desc": "Sangiovese grape is famous for its dry, bright cherry character", "price": 147.99 }
],
"comments": [
{ "id": 1, "body": "like the added grape skins", "wineId": 1 },
{ "id": 1, "body": "the directions need to be clearer", "wineId": 2 },
{ "id": 3, "body": "I received 3 different packages of wood chips", "wineId": 1 }
],
"profile": { "name": "vintnor" }
}
文件命名为db.json,然后我们就可以启动服务了。 简单的启动命令:
F:\jscode\json-server>json-server -w db.json
\{^_^}/ hi!
Loading db.json
Done
Resources
http://localhost:3000/posts
http://localhost:3000/comments
http://localhost:3000/profile
Home
http://localhost:3000
Type s + enter at any time to create a snapshot of the database
Watching...
我们可以指定定制的端口,-w 后面带着json文件即是lowdb的存储文件,可以通过-h命令查看json-server支持的参数。
F:\jscode\json-server>json-server -h
bin.js [options] <source>
Options:
-c, --config Path to config file
[default: "json-server.json"]
-p, --port Set port [default: 3000]
-H, --host Set host [default: "localhost"]
-w, --watch Watch file(s) [boolean]
-r, --routes Path to routes file
-m, --middlewares Paths to middleware files [array]
-s, --static Set static files directory
--read-only, --ro Allow only GET requests [boolean]
--no-cors, --nc Disable Cross-Origin Resource Sharing [boolean]
--no-gzip, --ng Disable GZIP Content-Encoding [boolean]
-S, --snapshots Set snapshots directory [default: "."]
-d, --delay Add delay to responses (ms)
-i, --id Set database id property (e.g. _id)
[default: "id"]
--foreignKeySuffix, --fks Set foreign key suffix (e.g. _id as in post_id)
[default: "Id"]
-q, --quiet Suppress log messages from output [boolean]
-h, --help Show help [boolean]
-v, --version Show version number [boolean]
Examples:
bin.js db.json
bin.js file.js
bin.js http://example.com/db.json
https://github.com/typicode/json-server
3.3 利用HTTPie来测试服务器
3.3.1 GET请求
HTTPie也是个好玩的python工具,类似于curl,我们这次用它来测试:
在另外终端输入:
http get http://localhost:3000/wines
显示如下:
可以支持更复杂的查询语法和我们平时写的springboot服务很像:
还支持正则表达式查询:
C:\Users\Think>http get http://localhost:3000/wines?product_like=TWO
HTTP/1.1 200 OK
Access-Control-Allow-Credentials: true
Cache-Control: no-cache
Connection: keep-alive
Content-Length: 154
Content-Type: application/json; charset=utf-8
Date: Sat, 22 Jul 2023 07:31:02 GMT
ETag: W/"9a-LGllsaww9QbJMJRaD+BGgkdFcJc"
Expires: -1
Keep-Alive: timeout=5
Pragma: no-cache
Vary: Origin, Accept-Encoding
X-Content-Type-Options: nosniff
X-Powered-By: Express
[
{
"desc": "Squeezed rapidly from a delicate, yet pretentious grape",
"id": "5",
"price": "2.99",
"product": "TWO-ISH BUCK CHUCK"
}
]
查询语法是在字段后面加上_like即可。 不敢相信,还支持全文检索,如下语法:
C:\Users\Think>http get http://localhost:3000/wines?q=yet
HTTP/1.1 200 OK
Access-Control-Allow-Credentials: true
Cache-Control: no-cache
Connection: keep-alive
Content-Length: 154
Content-Type: application/json; charset=utf-8
Date: Sat, 22 Jul 2023 07:32:52 GMT
ETag: W/"9a-LGllsaww9QbJMJRaD+BGgkdFcJc"
Expires: -1
Keep-Alive: timeout=5
Pragma: no-cache
Vary: Origin, Accept-Encoding
X-Content-Type-Options: nosniff
X-Powered-By: Express
[
{
"desc": "Squeezed rapidly from a delicate, yet pretentious grape",
"id": "5",
"price": "2.99",
"product": "TWO-ISH BUCK CHUCK"
}
]
3.3.2 POST请求添加数据
![image.png](https://i-blog.csdnimg.cn/blog_migrate/b1b0e6186333c0e9759b79792aab158a.png)
我们可以利用POST方法添加一条数据:
http POST localhost:3000/wines id=5 product="TWO BUCK CHUCK" price=2.99 desc="Squeezed rapidly from a delicate, yet unpretentious grape"
增加后通过id查询:
http get http://localhost:3000/wines/5
HTTP/1.1 200 OK
Access-Control-Allow-Credentials: true
Cache-Control: no-cache
Connection: keep-alive
Content-Length: 136
Content-Type: application/json; charset=utf-8
Date: Sat, 22 Jul 2023 07:24:09 GMT
ETag: W/"88-BPC094++pBcIJDHh/bbFUYN5tzY"
Expires: -1
Keep-Alive: timeout=5
Pragma: no-cache
Vary: Origin, Accept-Encoding
X-Content-Type-Options: nosniff
X-Powered-By: Express
{
"desc": "Squeezed rapidly from a delicate, yet unpretentious grape",
"id": "5",
"price": "2.99",
"product": "TWO BUCK CHUCK"
}
![POST请求](https://i-blog.csdnimg.cn/blog_migrate/064d7fe615f280eaea8374703bb293a9.png)
3.3.3 PUT请求修改数据
![image.png](https://i-blog.csdnimg.cn/blog_migrate/ae2c0597dfac1482de04cfb182c0b8f4.png)
PUT请求修改数据命令如下:
http PUT localhost:3000/wines/5 product="TWO-ISH BUCK CHUCK" price=2.99 desc="Squeezed rapidly from a delicate, yet pretentious grape"
![PUT请求](https://i-blog.csdnimg.cn/blog_migrate/0922ed5afeb9fb5e4bd1fff4c806b699.png)
3.3.4 删除数据
![删除数据](https://i-blog.csdnimg.cn/blog_migrate/5b4ba8721e7c6981be3f85ace8dcf359.png)
http DELETE localhost:3000/wines/5
![删除服务](https://i-blog.csdnimg.cn/blog_migrate/0dbab1098b49a3cb5dbb245fac3308e4.png)
4 简单的定制
如果我们需要授权访问,或需要很多定制数据,而且数据要是自己可以定制的,这时候就只能通过编码完成了,比如生成一千条数据
// index.js
module.exports = () => {
const data = { users: [] }
// Create 1000 users
for (let i = 0; i < 1000; i++) {
data.users.push({ id: i, name: `user${i}` })
}
return data
}
运行:
$ json-server index.js
测试:
C:\Users\Think>http get localhost:3000/users/1
HTTP/1.1 200 OK
Access-Control-Allow-Credentials: true
Cache-Control: no-cache
Connection: keep-alive
Content-Length: 32
Content-Type: application/json; charset=utf-8
Date: Sat, 22 Jul 2023 07:52:06 GMT
ETag: W/"20-UdPmwiEpoycb9u2K15k2zz81mIU"
Expires: -1
Keep-Alive: timeout=5
Pragma: no-cache
Vary: Origin, Accept-Encoding
X-Content-Type-Options: nosniff
X-Powered-By: Express
{
"id": 1,
"name": "user1"
}
对于我来说关键是定制请求和服务,可以通过下面的代码来实现:
const jsonServer = require('json-server')
const server = jsonServer.create()
const router = jsonServer.router('db.json')
const middlewares = jsonServer.defaults()
const { v4: uuidv4 } = require('uuid');
// Set default middlewares (logger, static, cors and no-cache)
server.use(middlewares)
const probeId = uuidv4();
console.log(probeId)
const registerResponse = {
"resultMessage":"注册成功",
"resultCode": 0,
"time": Date.now()/1000,
"data" : {
"id": "3KhOenUhjFI7Eg2A0Ovvr396SX2WIO8kgGvxMPvd8EHsu8Y2/mp3DMHy1DPoX0pX"
}
}
const heartbeatResponse = {
"resultMessage":"操作成功",
"resultCode": 0,
"time": Date.now()/1000
}
// Add custom routes before JSON Server router
server.get('/echo', (req, res) => {
res.jsonp(req.query)
})
server.post('/manage/register', (req, res) => {
res.jsonp(registerResponse)
})
server.post('/manage/heartbeat',(req,res) => {
res.jsonp(heartbeatResponse)
})
// To handle POST, PUT and PATCH you need to use a body-parser
// You can use the one used by JSON Server
server.use(jsonServer.bodyParser)
server.use((req, res, next) => {
if (req.method === 'POST') {
req.body.createdAt = Date.now()
}
// Continue to JSON Server router
next()
})
// Use default router
server.use(router)
server.listen(3000, () => {
console.log('JSON Server is running')
})
虽然代码比较长,但是大部分都是官方的例子的,定制的消息地方是:
// Add custom routes before JSON Server router
server.get('/echo', (req, res) => {
res.jsonp(req.query)
})
server.post('/manage/register', (req, res) => {
res.jsonp(registerResponse)
})
server.post('/manage/heartbeat',(req,res) => {
res.jsonp(heartbeatResponse)
})
不得不说nodejs对json的处理实在是太方便了,代码要正常运行还需要安装开发包:
$ npm install json-server --save-dev
运行定制服务:
F:\jscode\json-server\json>node server.js
JSON Server is running
测试,将请求的json放入文件hearbeat.json中,内容如下:
{"id":"3KhOenUhjFI7Eg2A0Ovvr396SX2WIO8kgGvxMPvd8EHsu8Y2/mp3DMHy1DPoX0pX","encryptTime":"ksySo5ll7c5kg0DGr9FF4Q==","time":"1690013067"}
请求命令如下:
F:\jscode\json-server\json>http -x post 127.0.0.1:3000/manage/heartbeat =@heartbeat.json
HTTP/1.1 200 OK
Access-Control-Allow-Credentials: true
Cache-Control: no-cache
Connection: keep-alive
Content-Length: 82
Content-Type: application/json; charset=utf-8
Date: Sat, 22 Jul 2023 08:19:09 GMT
ETag: W/"52-BOhF+g6Q+Rj2eKLuULBssIjnupA"
Expires: -1
Keep-Alive: timeout=5
Pragma: no-cache
Vary: Origin, Accept-Encoding
X-Content-Type-Options: nosniff
X-Powered-By: Express
{
"resultCode": 0,
"resultMessage": "操作成功",
"time": 1690012803.145
}
可以看到,我们完成了消息定制的功能。
好,打完手工。
本文由 mdnice 多平台发布