持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第15天,点击查看活动详情
在之前的文章中曾用原生Node.js,也就是内置的http模块,搭建了一个简易的服务器,最直观的体验就是处理路由时非常复杂,并且需要自己指定状态码和头部信息。
本文就使用Node.js的简易框架Express来解决以上问题,并简单做一下延伸,通过阅读本文,你将初步学会使用Express来:
- 搭建简易服务器,实现基本的路由导航
- 向
API发送GET请求,使用路由参数,将本地JSON数据发送到客户端 - 利用中间件向
API发送POST请求,从而往JSON文件添加内容
开发工具
nodemon
建议大家先安装一下Nodemon,它之于index.js,类似于Live Server之于index.html:
以往要执行一个脚本,需要使用node index.js命令,如果index.js中的文件内容发生了变化,就需要重新执行一次,安装Nodemon之后,只需要使用nodemon index.js命令运行一次,之后如果脚本内容发生变化,nodemon会自动帮助我们重新运行。
安装命令如下:
npm install nodemon --save-dev -g
建议全局安装,这样在其它项目中也能使用
Postman
为了方便调试API接口,建议安装Postman,从官网下载安装包,一路Next完成安装
用Express搭建服务器
在以下代码中,我们使用Express搭建了一个简易HTTP服务器,并定义了GET请求和POST请求的响应内容:
// index.js
const express = require('express');
const app = express();
app.get('/', (req, res) => {
res
.status(200)
.json({ message: 'Hello from the server side!', app: 'Natours' });
});
app.post('/', (req, res) => {
res.send('You can post to this endpoint');
});
const port = 3000;
app.listen(port, () => {
console.log(`App running on port ${port}...`);
});
在命令行输入nodemon index.js,可以看到每次index.js有所改动时,nodemon都会自动帮我们启动服务器:
代码解读:
- 我们首先用
express()函数创建一个服务器对象 - 然后用路由定义方法
app.get和app.post定义了主页/的路由:res.status用于设置状态码,res.json用于向客户端发送JSON文件,将Content-type设置为application/json - 最后调用
listen方法在3000端口开启服务器
接口测试:下面用Postman测试下接口,可以看到响应内容和状态码都对着呢:
GET请求
下面我们来使用GET请求获取本地的JSON数据:
const express = require('express');
const fs = require('fs');
const app = express();
const tours = JSON.parse(
fs.readFileSync(`${__dirname}/dev-data/data/tours-simple.json`)
);
app.get('/api/v1/tours', (req, res) => {
res.status(200).json({
status: 'success',
results: tours.length,
data: {
tours,
},
});
});
const port = 3000;
app.listen(port, () => {
console.log(`App running on port ${port}...`);
});
可以看到跟上面那个例子相比,没有特殊的地方,只是增加了使用fs模块来读取本地JSON文件的部分,在Postman中测试接口127.0.0.1:3000/api/v1/tours的结果如下:
上面获取的是全部的JSON数据,实际开发中,我们可能只是按需获取JSON文件中的部分数据,比如接口/api/v1/tours/1返回的是一组数据,/api/v1/tours/5返回的又是另一组数据,下面将用路由参数实现这个需求
......
app.get('/api/v1/tours/:id', (req, res) => {
const id = req.params.id * 1; // 字符串转换成数字
const tour = tours.find(el => el.id === id);
if (!tour) {
return res.status(404).json({
status: 'fail',
message: 'Invalid ID',
});
}
res.status(200).json({
status: 'success',
data: {
tour,
},
});
});
......
代码解读:
- 通过在路由中使用冒号
:就可以定义变量,并使用req.params来获取变量值。在上面的代码中,定义的变量是id,它的值由接口决定,需要注意的是req.params.id获取的数据格式是字符串,这里利用运算将其转换成了数字 - 利用数组的
.find方法来匹配id的值与JSON内容,最后得到对应的数据tour,返回给客户端 - 针对
JSON文件中没有的数据,将状态码设置为404,并返回相关的错误信息
接口测试:
POST请求
仅仅获取数据怎么能满足我们的需求呢,下面我们用中间件和POST请求来向JSON文件中添加数据,代码如下:
const express = require('express');
const fs = require('fs');
const app = express();
// 中间件
app.use(express.json());
const tours = JSON.parse(
fs.readFileSync(`${__dirname}/dev-data/data/tours-simple.json`)
);
app.post('/api/v1/tours', (req, res) => {
const newId = tours[tours.length - 1].id + 1;
const newTour = Object.assign({ id: newId }, req.body);
tours.push(newTour);
fs.writeFile(
`${__dirname}/dev-data/data/tours-simple.json`,
JSON.stringify(tours),
() => {
res.status(201).json({
status: 'success',
data: {
tours,
},
});
}
);
});
const port = 3000;
app.listen(port, () => {
console.log(`App running on port ${port}...`);
});
代码解读:
- 中间件
express.json()的中间,指的是请求和响应的中间。这个案例中我们仅仅需要知道发送POST请求时需要app.use(express.json());这么一行代码就行了,关于中间件的详细介绍笔者后面会专门写一篇文章 - 这里为添加的内容为
newId和请求头,即req.body的内容,使用Object.assign()将内容合并到一个对象中,通过fs.writeFile写入到本地JSON文件中,并将最新的数据返回给客户端
接口测试:
下面在Postman中发送一个POST请求,来验证代码:
Body中我们选中数据格式为
JSON,并添加了name和duration两个属性值,发送POST请求之后,可以看到响应体中增加了写入的内容,并且状态码为201 Created🍺🍺🍺
总结
文本循序渐进向大家演示了如何使用Express来创建HTTP服务器以及定义路由,然后结合Postman展示了如何使用路由参数来发送GET请求以获取本地JSON数据,以及如何利用中间件发送POST请求来添加数据。