基本Demo
创建express,设置路由,响应,监听端口号
//引入express
const express = require('express')
//创建App
const app = express()
// 配置路由
app.get('/', (req, res) => {
res.send('hello express')
})
// 监听端口号
app.listen(5566, () => {
console.log('启动成功');
})
路由基础
路由是指定应用程序如何响应客户端对特定端点的请求,该特定端点是URI和特定请求方法。 每个路由可以有一个或多个处理程序函数,这些函数在匹配该路由时执行。
路由定义使用以下结构:
app.method(路径,处理器(就是回调方法))
请求和响应对象
一个请求对象主要包括这些部分:请求地址、请求方法、请求头、请求体
app.get('/', (req, res) => {
console.log(req.url); //url
console.log(req.method); //请求方法
console.log(req.headers); //请求头
console.log(req.body); //请求体
console.log(req.query) //请求参数
res.send('hello express')
})
由于仅仅访问“/”路径,请求体里面没有写任何东西所以是undefined
响应对象继承自http.ServerResponse类,支持以下操作
app.post('/res', (req, res) => {
//res.send('hello express')
console.log(res.status); //状态码
res.write('a') //发送多段文本
res.write('b')
res.write('c')
res.end() //结束响应
})
注意:res前面不能有res.send()
练习001-基本操作
练习基本操作配置路由,获取列表数据、添加、删除、模仿数据库、封装操作
先创建一个JSON文件用于增删改查数据,模拟数据库
{
"todos": [
{
"id": "1",
"title": "C"
},
{
"id": "2",
"title": "Java"
},
{
"id": "3",
"title": "JavaScript"
},
{
"id": "4",
"title": "swift"
}
],
"users": []
}
创建app.js进行服务搭建
const app = express()
// 配置解析请求体,否则无法读取对应格式的请求体 application/json
app.use(express.json())
// x-www-form-urlencoded格式
app.use(express.urlencoded())
//获取全部数据
app.get('/todos', async (req, res) => {
fs.readFile('./db.json', 'utf-8', (err, data) => {
if (err) {
return res.status(500).json({
error: err.message
}) //json()方法专门用于发送json数据
}
const db = JSON.parse(data)
res.status(200).json(db.todos)
})
res.send('get 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
}) //json()方法专门用于发送json数据
}
const db = JSON.parse(data)
const todo = db.todos.find(todo => todo.id === req.params.id) //查找对应id的数据
if (!todo) {
return res.status(404).json({
error: err.message
})
}
res.status(200).json(todo)
})
// req.params获取动态路径参数
// res.send(`get todo:${req.params.id}`)
})
响应成功
但是上面的请求存在文件读取的重复代码,需要进行封装,创建一个db.js文件,对存取操作进行封装
const fs = require('fs')
//promisify自动转换
const {promisify} = require('util')
const path = require('path')
// 为了减少回调方法把fs.readFile转为Promise形式
const readFile = promisify(fs.readFile)
const writeFile = promisify(fs.writeFile)
// 获取路径
const dbPath = path.join(__dirname, './db.json')
// 获取列表 async标记异步
exports.getDB = async () => {
const data = await readFile(dbPath, 'utf-8')
return JSON.parse(data)
}
// 存储列表
exports.saveDB = async (db) => {
const data = JSON.stringify(db)
await writeFile(dbPath, data)
}
修改后的读取操作
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
}) //json()方法专门用于发送json数据
}
})
app.get('/todos/:id', async (req, res) => {
try {
const db = await getDB()
const todo = db.todos.find(todo => todo.id === req.params.id) //查找对应id的数据
if (!todo) {
return res.status(404).json({
error: err.message
})
}
res.status(200).json(todo)
} catch (err) {
res.status(500).json({
error: err.message
}) //json()方法专门用于发送json数据
}
})
获取成功
添加数据,其中我的id默认是字符串类型,添加时需要进行两次类型转换
//添加数据
app.post('/todos', async (req, res) => {
try {
// 第一步:获取客户端请求体参数
const todo = req.body
// 第二步:数据验证
if (!todo.title) {
return res.status(422).json({
error: 'title字段不可缺少'
})
}
const db = await getDB()
db.todos.push({
id: (Number.parseInt(db.todos[db.todos.length - 1].id) + 1).toString(),
title: todo.title
})
// 第三步:数据验证通过,把数据存储到DB中
// db.todos.push(todo)
await saveDB(db)
// 第四步发送响应
res.status(200).json(todo)
} catch (err) {
res.status(500).json({
error: err.message
})
}
})
添加成功
以下是服务的代码(学的杂,怕忘了)
const express = require('express')
const fs = require('fs')
const { getDB, saveDB } = require('./db')
const app = express()
// 配置解析请求体,否则无法读取对应格式的请求体 application/json
app.use(express.json())
// 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
}) //json()方法专门用于发送json数据
}
})
app.get('/todos/:id', async (req, res) => {
try {
const db = await getDB()
const todo = db.todos.find(todo => todo.id === req.params.id) //查找对应id的数据
if (!todo) {
return res.status(404).json({
error: err.message
})
}
res.status(200).json(todo)
} catch (err) {
res.status(500).json({
error: err.message
}) //json()方法专门用于发送json数据
}
})
//添加数据
app.post('/todos', async (req, res) => {
try {
// 第一步:获取客户端请求体参数
const todo = req.body
// 第二步:数据验证
if (!todo.title) {
return res.status(422).json({
error: 'title字段不可缺少'
})
}
const db = await getDB()
db.todos.push({
id: (Number.parseInt(db.todos[db.todos.length - 1].id) + 1).toString(),
title: todo.title
})
// 第三步:数据验证通过,把数据存储到DB中
// db.todos.push(todo)
await saveDB(db)
// 第四步发送响应
res.status(200).json(todo)
} catch (err) {
res.status(500).json({
error: err.message
})
}
})
app.listen(5566, () => {
console.log('项目已运行在5566端口上');
})
修改
// 修改
app.patch('/todos/:id', async (req, res) => {
try {
// 获取表单数据
const todo = req.body
// 查找需要修改的数据
const db = await getDB()
const ret = db.todos.find(todo => todo.id === req.params.id)
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 = 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
})
}
})
已经没有id为2的数据了