Node.js服务端之express系统过一下-01

244 阅读4分钟

基本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的数据了