需求:实现对任务清单的CRUD接口服务
查询任务列表 GET/todos
根据ID查询单个任务 GET/todos/:id
添加任务 POST/todos
修改任务 PATCH/todos/:id
删除任务 DELETE/todos/:id
由于这些请求中有相同的部分,所以我们进行一个封装
db.js
const fs = require('fs')
const { promisify } = require('util')
const path = require('path')
const readFile = promisify(fs.readFile)
const writeFile = promisify(fs.writeFile)
const dbpath = path.join(__dirname, './db.json')
exports.getDb = async () => {
const data = await readFile(dbpath, 'utf-8')
return JSON.parse(data)
}
exports.saveDb = async db => {
// const data = JSON.stringify(db) 这样写,db.json将没有缩进,下面这样写有缩进
const data = JSON.stringify(db, null, ' ')
await writeFile(dbpath, data)
}
app.js(主体代码)
const express = require('express')
const fs = require('fs')
const { getDb, saveDb } = require('./db')
const app = express()
// 解析表单请求体:application/json
app.use(express.json())
// 解析表单请求体:application/x-www-form-urlencoded
app.use(express.urlencoded())
app.get('/todos', async (req,res) => {
try {
const db = await getDb()
res.status(200).json(db.todos)
} catch(err) {
res.status(500).json({
error: err.message
})
}
})
app.get('/todos/:id', async (req,res) => {
try {
const db = await getDb()
const todo = db.todos.find(todo => todo.id === Number.parseInt(req.params.id))
if (!todo) {
return res.status(404).end()
}
res.status(200).json(todo)
} catch (err) {
res.status(500).json({
error: err.message
})
}
})
app.post('/todos', async (req,res) => {
try {
// 1. 获取客户端请求体参数
const todo = req.body
// 2. 数据验证
if (!todo.title) {
res.status(422).json({
errro: 'The field title is required.'
})
}
// 3. 数据验证通过,把数据存储到db中
const db = await getDb()
const lastTodo = db.todos[db.todos.length - 1]
todo.id = lastTodo ? lastTodo.id + 1 : 1
db.todos.push(todo)
await saveDb(db)
// 4. 发送响应
res.status(201).json(todo)
} catch(err) {
res.status(500).json({
error: err.message
})
}
})
app.patch('/todos/:id', async (req,res) => {
try {
// 1. 获取表单数据
const todo = req.body
// 2. 查找到要修改的任务项
const db = await getDb()
const ret = db.todos.find(todo => todo.id === Number.parseInt(req.params.id))
console.log(ret)
if (!ret) {
return res.status(404).end()
}
Object.assign(ret, todo)
await saveDb(db)
res.status(200).json(ret)
} catch (err) {
res.status(500).json({
error: err.message
})
}
})
app.delete('/todos/:id', async (req,res) => {
try {
const todoId = Number.parseInt(req.params.id)
const db = await getDb()
const index = db.todos.findIndex(todo => todo.id === todoId)
if (index === -1) {
return res.status(404).end()
}
db.todos.splice(index, 1)
await saveDb(db)
res.status(204).end()
} catch(err) {
res.status(500).json({
error: err.message
})
}
})
app.listen(3000, () => {
console.log(`Server running at http://localhost:3000/`)
})
db.json
{
"todos": [
{
"id": 1,
"title": "干饭"
},
{
"id": 2,
"title": "睡觉"
},
{
"id": 3,
"title": "写代码"
}
],
"users": []
}
效果
查询任务列表
根据ID查询单个任务
根据ID查询失败
添加任务
db.json
{
"todos": [
{
"id": 1,
"title": "干饭"
},
{
"id": 2,
"title": "睡觉"
},
{
"id": 3,
"title": "写代码"
},
{
"title": "追番",
"id": 4
}
],
"users": []
}
修改任务
db.json
{
"todos": [
{
"id": 1,
"title": "跑步"
},
{
"id": 2,
"title": "睡觉"
},
{
"id": 3,
"title": "写代码"
}
],
"users": []
}
删除任务
db.json
{
"todos": [
{
"id": 1,
"title": "干饭"
},
{
"id": 3,
"title": "写代码"
}
],
"users": []
}