express寫CRUD需求接口案例

需求:實現(xiàn)對任務(wù)清單的CRUD接口服務(wù)

  • 查詢?nèi)蝿?wù)列表
    GET /todos

  • 根據(jù) ID 查詢單個任務(wù)
    GET /todos/:id

  • 添加任務(wù)
    POST /todos

  • 修改任務(wù)
    PATCH /todos/:id

  • 刪除任務(wù)

DELETE /todos/:id

目錄結(jié)構(gòu)及啟動示意圖

代碼視圖

  • app.js項目入口文件
const express = require('express')
const fs = require('fs')
const { getDb, saveDb } = require('./db')
const app = express()
const bodyParser = require('body-parser') 
app.use(express.json()) //配置解析表單請求頭:application/json
app.use(express.urlencoded()) //配置解析表單請求頭:application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({ extended: false }))

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
        })
    }
})

/** 2.增加接口**/
app.post('/todos', async (req, res) => {
    try {
        const todo = req.body // 1.獲取客戶端請求參數(shù)
        console.log(todo.title);
        if (!todo.title) { // 2.數(shù)據(jù)驗證
            return res.status(422).json({
                error: 'The field title is required.'
            })
        }
        // 3.數(shù)據(jù)驗證通過,把數(shù)據(jù)存儲到db中
        const db = await getDb()
        const lastTodo = db.todos[db.todos.length - 1]
        //id唯一,重新寫入到db文件中不覆蓋,db文件是空的話,id = 1
        todo.id = lastTodo ? lastTodo.id + 1 : 1,
        db.todos.push(todo)
        await saveDb(db) //保存文件
        // 4.發(fā)送響應(yīng)
        res.status(201).json(todo)
    } catch (err)  {
        res.status(500).json({
            error: err.message
        })
    }
})

/* 3.修改接口 */
app.patch('/todos/:id', async (req, res) => {
    try {
      const todo = req.body //獲取表單數(shù)據(jù)
      //查找到要修改的任務(wù)項
      const db = await getDb()
      const result = db.todos.find(todo => todo.id === Number.parseInt(req.params.id))
      if(!result){ //修改項不存在
          return res.status(404).end()
      }
      Object.assign(result,todo) //合并數(shù)據(jù)
      await saveDb(db) //數(shù)據(jù)存儲
      res.status(200).json(result)
    } catch (err) {
        res.status(500).json({
            error: err.message
        })
    }
})

/* 4.刪除接口 */
app.delete('/todos/:id', async (req, res) => {
    try {
        //查找到要修改的任務(wù)項
        const todoId = Number.parseInt(req.params.id)
        const db = await getDb() //獲取數(shù)據(jù)庫
        const index = db.todos.findIndex(todo => todo.id === todoId) //根據(jù)索引進行刪除
        if(index === -1){ // -1代表找不到
            return res.status(404).end
        }
        db.todos.splice(index,1) //根據(jù)索引刪除一項
        await saveDb(db) //數(shù)據(jù)存儲
        res.status(204).end() //發(fā)送狀態(tài)碼并且結(jié)束響應(yīng)
      } catch (err) {
          res.status(500).json({
              error: err.message
          })
      }
})

app.listen(3000, () => {
    console.log('Server is running at http://localhost:3000');
})


/*
    沒封裝db.js的寫法
*/
// app.get('/todos', (req, res) => {
//     fs.readFile('./db.json', 'utf-8', (err, data) => {
//         if (err) {
//             res.status(500).json({
//                 error: err.message
//             })
//         }
//         const db = JSON.parse(data)
//         res.status(200).json(db.todos)
//     })
// })
  • db.js 是一個封裝好的db模塊,封裝了用于讀取和保存數(shù)據(jù)的方法。
/*
    封裝db模塊
*/

const fs = require('fs')
const { promisify } = require('util')
const readFile = promisify(fs.readFile) //提供promise支持的異步讀文件操作
const writeFile = promisify(fs.writeFile)
const path = require('path')

const dbPath = path.join(__dirname,'./db.json') //動態(tài)拼接路徑 
exports.getDb = async () => {
    const data = await readFile(dbPath, 'utf-8')
    return JSON.parse(data) //讀取json文件并轉(zhuǎn)換
}

exports.saveDb = async db => {
    const data = JSON.stringify(db, null, '  ') //后2個參數(shù)讓寫入內(nèi)容的時候是換行對其
    await writeFile(dbPath, data)
}
  • db.json 模擬充當(dāng)數(shù)據(jù)庫存儲
{
  "todos": [
    {
      "id": 1,
      "title": "看電視"
    },
    {
      "id": 2,
      "title": "吃飯"
    },
    {
      "id": 3,
      "title": "敲代碼"
    },
    {
      "title": "看電視",
      "id": 4
    }
  ],
  "users": []
}

Postman工具測試檢驗接口

  1. 查詢?nèi)蝿?wù)列表


  2. 根據(jù)ID查詢單個任務(wù)


  3. 添加任務(wù)項



    我們再來看看db.json有沒有多出了id為5的任務(wù)項。


  4. 根據(jù)ID修改查詢到的單個任務(wù)



    db.json有沒有修改成功?


  5. 根據(jù)ID刪除查詢到的單個任務(wù)



    db.json查看還有沒有id為4的任務(wù)項。


express.json()和express.urlencoded()的區(qū)別

以POSTMAN工具為例子

  • 總結(jié):express.urlencoded()以鍵值對的形式填寫請求,express.json()以json格式填寫請求.
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容