一、express路由
-
动态路由参数 params
-
路径参数 query
二、 todos案例
2.1 准备工作
- 新建一个文件夹01-demo
- 执行
npm init -y
生成package.json配置文件 - 执行
npm install express --save
安装express - 新建app.js文件,这是程序的入口文件
- 新建db.json文件,用来保存数据
- 新建db.js 模拟 用来操作数据库
2.2 编写接口相关的代码
app.js文件:
const express = require('express')
const fs = require('fs')
const app = express()// 配置解析表单请求体: application/json
app.use(express.json())
// 配置解析表单请求体: application/x-www-form-urlencoded
app.use(express.urlencoded())const { getDb, saveDb } = require('./db.js')app.get('/', (req, res) => {// console.log(req.url)// console.log(req.method)// console.log(req.headers)// console.log(req.query)// res.send('hello express')// 设置响应状态码// res.statusCode = 201// 结束响应// res.end()// res.send({// foo: 'bar'// })// res.cookie('foo', 'bar')// res.status(201).send('ok')
})// 查询任务列表
app.get('/todos', async (req, res) => {// fs.readFile('./db.json', 'utf8', (err, data) => {// if(err) {// res.status(500).json({// error: err.message// })// return;// }// const db = JSON.parse(data)// res.status(200).json(db.todos)// })try {const db = await getDb()res.status(200).json(db.todos)} catch (err) {if (err) {res.status(500).json({error: err.message})}}
})
// 根据id查询单个任务
app.get('/todos/:id', async (req, res) => {try {const db = await getDb()const todo = db.todos.find(todo => {return 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})}// fs.readFile('./db.json', 'utf8', (err, data) => {// if (err) {// return res.status(500).json({// error: err.message// })// }// const db = JSON.parse(data)// const todo = db.todos.find(todo => {// return todo.id === Number.parseInt(req.params.id)// })// if (!todo) {// return res.status(404).end()// }// res.status(200).json(todo)// })
})
// 添加任务
app.post('/todos', async (req, res) => {try {// 1. 获取客户端请求体参数console.log(req.body)const todo = req.body// 2. 数据验证if(!todo.title) {return res.json({error: '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 : 1db.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 => {return todo.id === Number.parseInt(req.params.id)})if(!ret) {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) => {return 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.js文件:
const fs = require('fs')
const { promisify } = require('util')
// node内置的util模块的promisify()可以把普通的函数包装成promise
const readFile = promisify(fs.readFile)
const writeFile = promisify(fs.writeFile)const path = require('path')
const dbPath = path.join(__dirname, './db.json')exports.getDb = async () => {const data = await readFile(dbPath, 'utf8')return JSON.parse(data)
}exports.saveDb = async (db) => {const data = JSON.stringify(db, null, ' ')await writeFile(dbPath, data)}
db.json文件:
{"todos": [{"id": 1,"title": "修改数据"},{"id": 2,"title": "修改数据2"},{"id": 3,"title": "打豆豆"},{"title": "笨小孩","id": 4},{"title": "笨小孩5","id": 5}],"users": []
}