1.案例
通过创建一个简单的CURD接口服务,从而掌握Express的基本用法。
需求:实现对任务清单的CURD接口服务。
- 查询任务列表
GET /todos
- 根据ID查询单个任务
GET /todos/:id
- 添加任务
POST /todos
- 修改任务
PATCH /todos/:id
- 删除任务
DELETE /todos/:id
2.路由设计
路由设计代码,如下:
const express = require('express');
const app = express()
// 查询任务
app.get('/todos', (req, res) => {
res.send('get /todos')
})
// 查询单个任务
app.get('/todos/:id', (req, res) => {
//通过req.params来获取动态的路由地址
res.send(`get /todos/${req.params.id}`)
})
// 添加任务
app.post('/todos', (req, res) => {
res.send('post /todos')
})
// 修改任务
app.patch('/todos/:id', (req, res) => {
res.send(`patch /todos/${req.params.id}`)
})
// 删除任务
app.delete('/todos/:id', (req, res) => {
res.send(`delete /todos/${req.params.id}`)
})
app.listen(3000, () => {
console.log('server is running!!')
})
复制代码
3.查询任务
3.1 新建一个db.json文件,用来存放数据,内容如下:
{
"todos": [
{
"id": 1,
"name": "降龙十八掌"
},
{
"id": 2,
"name": "独孤九剑"
},
{
"id": 3,
"name": "九阳神功"
}
],
"users": []
}
复制代码
3.2 修改查询任务的代码,如下
const express = require('express');
const app = express()
const fs = require('fs')
// 查询任务
app.get('/todos', (req, res) => {
fs.readFile('db.json', 'utf-8', (err, data) => {
if (err) {
return res.status(500).json({
error: err.message
})
}
var db = JSON.parse(data)
res.status(200).json(db.todos)
})
})
// 查询单个任务
app.get('/todos/:id', (req, res) => {
res.send(`get /todos/${req.params.id}`)
})
// 添加任务
app.post('/todos', (req, res) => {
res.send('post /todos')
})
// 修改任务
app.patch('/todos/:id', (req, res) => {
res.send(`patch /todos/${req.params.id}`)
})
// 删除任务
app.delete('/todos/:id', (req, res) => {
res.send(`delete /todos/${req.params.id}`)
})
app.listen(3000, () => {
console.log('server is running!!')
})
复制代码
思路:通过Nodejs的读文件功能,读取文件,返回的是字符串格式(注意设置成utf-8),然后,将json字符串转成json格式返给客户端。
4.查询单个数据
查询单个任务的代码,如下:
const express = require('express');
const app = express()
const fs = require('fs')
// 查询任务
app.get('/todos', (req, res) => {
fs.readFile('db.json', 'utf-8', (err, data) => {
if (err) {
return res.status(500).json({
error: err.message
})
}
var db = JSON.parse(data)
res.status(200).json(db.todos)
})
})
// 查询单个任务
app.get('/todos/:id', (req, res) => {
fs.readFile('db.json', 'utf-8', (err, data) => {
if (err) {
return res.status(500).json({
error: err.message
})
}
var db = JSON.parse(data)
var todo = db.todos.find(todo => todo.id.toString() === req.params.id);
if (!todo) {
return res.status(404).json({
data: 'not found'
})
}
res.status(200).json(todo)
})
})
// 添加任务
app.post('/todos', (req, res) => {
res.send('post /todos')
})
// 修改任务
app.patch('/todos/:id', (req, res) => {
res.send(`patch /todos/${req.params.id}`)
})
// 删除任务
app.delete('/todos/:id', (req, res) => {
res.send(`delete /todos/${req.params.id}`)
})
app.listen(3000, () => {
console.log('server is running!!')
})
复制代码
思路:和查询全部数据的思路一样,查到全部数据之后,根据传过来的id和读取到的数据进行比较,这里要注意
地址栏获取的参数是字符串类型,json数据中的id是number类型,需要转换以下
,然后,判断以下是否查到了数据,如果查到了返回该数据,如果没查到返回404,not fount
5.封装db模块
思考:考虑到目前查询全部数据的功能和查询单条数据的功能中,获取数据的代码都一样,我们可以对他们进行封装以下。
新建db.js,内容如下:
const fs = require('fs');
const { promisify } = require('util');
const path = require('path')
const readFile = promisify(fs.readFile)
const dbPath = path.join(__dirname, './db.json')
exports.getDb = async () => {
let data = await readFile(dbPath, 'utf8')
return JSON.parse(data)
}
复制代码
promisify
: 将异步回调的方法处理成promise
index.js文件,代码修改如下:
const express = require('express');
const app = express()
const fs = require('fs')
const { getDb } = require('./db')
// 查询任务
app.get('/todos', async (req, res) => {
try {
let db = await getDb();
res.status(200).json(db.todos);
} catch (err) {
res.status(500).json({
error: err.message
})
}
// fs.readFile('db.json', 'utf-8', (err, data) => {
// if (err) {
// return res.status(500).json({
// error: err.message
// })
// }
// var db = JSON.parse(data)
// res.status(200).json(db.todos)
// })
})
// 查询单个任务
app.get('/todos/:id', async (req, res) => {
try {
let db = await getDb();
let todo = db.todos.find(todo => todo.id.toString() === req.params.id);
if (!todo) {
return res.status(404).json({
data: 'not found'
})
}
res.status(200).json(todo)
} catch {
res.status(500).json({
error: err.message
})
}
// fs.readFile('db.json', 'utf-8', (err, data) => {
// if (err) {
// return res.status(500).json({
// error: err.message
// })
// }
// var db = JSON.parse(data)
// var todo = db.todos.find(todo => todo.id.toString() === req.params.id);
// if (!todo) {
// return res.status(404).json({
// data: 'not found'
// })
// }
// res.status(200).json(todo)
// })
})
// 添加任务
app.post('/todos', (req, res) => {
res.send('post /todos')
})
// 修改任务
app.patch('/todos/:id', (req, res) => {
res.send(`patch /todos/${req.params.id}`)
})
// 删除任务
app.delete('/todos/:id', (req, res) => {
res.send(`delete /todos/${req.params.id}`)
})
app.listen(3000, () => {
console.log('server is running!!')
})
复制代码
通过async和await来获取到异步的数据,然后,通过try..Catch..来捕获异常信息
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END