路由
路由是指确定应用程序如何响应客户端对特定端点的请求,该特定端点是 URI(或路径)和特定的 HTTP 请求方法app.method(path,handler)
app 是 express 的实例
method 是小写的 http 请求方法
path 是请求路径
handler 是处理函数
在根路径响应GET
app.get("/", (req, res) => {
res.send("Hello World");
});
在根路径响应POST
请求
app.post("/", (req, res) => {
res.send("Get a post request");
});
响应/user
路径的PUT
请求
app.put("/user", (req, res) => {
res.send(`Get a put request at /user`);
});
响应对/user
路径的DELETE
请求
app.delete("/user", (req, res) => {
res.send("Get a delete request at /user");
});
请求和响应
Express 应用使用路由回调函数的参数request
和response
对象来处理请求和响应的数据。
Express 不对 Node.js 已有的特性进行二次抽象,只是在它之上扩展了 web 应用所需的基本功能。
- 内部使用的还是
http
模块 - 请求对象继承自
http.IncommingMessage
- 响应对象继承自
http.ServerResponse
app.get("/", (request, response) => {
// todo something
});
请求对象
请求对象request:就是用来获取请求相关的信息
属性 | 说明 |
---|---|
req.app | 获取应用程序实例 |
req.baseUrl | 获取请求的地址 |
req.headers | 获取请求头 |
req.method | 获取请求方法 |
req.app | |
req.app | |
req.app |
响应对象
案例
// app.js
const express = require(‘express‘)
const app = express()
// 配置解析表单请求体--解析json格式数据
app.use(express.json())
// 解析x-www-form-urlencoded格式数据
app.use(express.urlencoded())
const { getdb, saveDb } = require("./lib/db.js")
// 查询任务列表
app.get("/todos", async (req, res) => {
try {
const db = await getdb()
res.status(200).json(db.todos)
} catch (error) {
res.status(500).json({
error: error.message
})
}
});
// 根据id查询单个任务
app.get(‘/todos/:id‘, async (req, res) => {
try {
const db = await getdb()
const todo = db.todos.find(item =>
item.id === Number.parseInt(req.params.id)
)
if (!todo) {
return res.status(404).end()
}
res.status(200).json(todo)
} catch (error) {
res.status(500).json({
error: error.message
})
}
})
// 添加任务
app.post("/todos", async (req, res) => {
/**
* 1. 获取客户端请求体参数
* 2. 数据验证
* 3. 数据验证,把数据存储到db中
* 4. 发送响应
*/
try {
const todo = req.body
if (!todo.title) {
return res.status(422).json({
error: ‘the field title is required‘
})
}
const db = await getdb()
const lastTodo = db.todos[db.todos.length - 1]
console.log(lastTodo)
// 给请求体中添加id属性
todo.id = lastTodo ? (lastTodo.id + 1) : 1
db.todos.push(todo)
await saveDb(db)
res.status(200).json(todo)
} catch (error) {
res.status(500).json({
error: error.message
})
}
});
// 修改任务
app.patch(‘/todos/:id‘, async (req, res) => {
try {
// 1.获取表单数据
const todo = req.body
// 2. 查找要修改的任务项
const db = await getdb()
const result = db.todos.find(item => item.id === Number.parseInt(req.params.id))
if (!result) {
return res.status(404).end()
}
// 包todo中的数据合并到result中
Object.assign(result, todo)
await saveDb(db)
// 3. 发送响应
res.status(201).json(result)
} catch (error) {
res.status(500).json({
error: error.message
})
}
})
// 删除任务
app.delete("/todos/:id", async (req, res) => {
try {
const todoId = Number.parseInt(req.params.id)
let db = await getdb()
let index = db.todos.findIndex(item => item.id === todoId)
// console.log(index)
if (index === -1) {
return res.status(404).end()
}
db.todos.splice(index, 1)
await saveDb(db)
// 删除返回204
res.status(204).end()
} catch (error) {
res.status(500).json({
error: error.message
})
}
});
app.listen(3000, () => {
console.log(`server is running 3000`)
})
// db.js
const fs = require(‘fs‘)
const {
promisify
} = require(‘util‘)
const readFile = promisify(fs.readFile)
const writeFile = promisify(fs.writeFile)
const path = require(‘path‘)
const db_path = path.join(__dirname, ‘./db.json‘)
exports.getdb = async () => {
const data = await readFile(db_path, ‘utf-8‘)
return JSON.parse(data)
}
exports.saveDb = async (db) => {
// 有回车换行 缩进两个字符
const data = JSON.stringify(db,null,‘ ‘)
await writeFile(db_path, data)
}
{
"todos": [
{
"title": "Postman",
"id": 1
},
{
"title": "Testman",
"id": 2
}
],
"user": []
}