【Express】基本用法:实现对任务列表的CRUD的接口服务

该文描述了一个使用Express框架构建的RESTfulAPI,实现了对todos任务的CRUD操作,包括查询任务列表、按ID查询任务、添加任务、修改任务和删除任务。数据存储在db.json文件中,通过异步读写文件的方法进行处理。每个操作都关注了HTTP状态码的正确返回。
摘要由CSDN通过智能技术生成

路由及其他要求:

  • 查询任务列表:GET /todos

  • 根据ID查询单个任务:GET /todos/:id

  • 添加任务:POST /todos

  • 修改任务:PATCH /todos

  • 删除任务:DELETE /todos/:id

  • 假设任务列表db.json如下:

{
    "todos": [
        {
            "id": 001,
            "title": "research"
        },
        {
            "id": 002,
            "titlo": "write papers"
        },
        {
            "id": 003,
            "title": "coding"
        }
    ],
    "users": []
}

实现过程:

在发起多个请求的过程中,会出现重复获取任务列表的情况,故对其进行一个简单的封装。对db.json的操作封装到db.js文件内.

db.js:

const fs = require('fs')
const { promisify } = require('util') // util所提供的promisify方法能够把callback这种形式的异步api转换成promise的方式
const path = require('path')

const readFile = promisify(fs.readFile)

const dbPath = path.join(__dirname, './db.json') //dirname代表当前所在文件路径
//path.join()方法使用特定于平台的分隔符作为定界符将所有给定的 path 片段连接在一起,然后规范化生成的路径。

exports.getDb = async () => {
    const data = await readFile(dbPath, 'utf8')
    return JSON.parse(data)
}

主体代码app.js

// import express from 'express'
const express = require('express')
const fs = require('fs')
const { getDb, saveDb } = require('./db')

const app = express()
// 配置解析表单请求体:application/json
app.use(express.json()) //把客户端提交过来的数据按照JSON格式转换成js对象
//  配置解析表单请求体:application/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
        })
    }
})

/* 根据ID查询单个任务 */
app.get('/todos/:id', async (req, res) => {
    // console.log(typeof req.params.id)
    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
        })
    }
})

/* 添加任务 */
app.post('/todos', async (req, res) => {
    try {
        // 1. 获取客户端请求体参数
        // console.log(req.body)
        const todo = req.body
        // 2. 数据验证
        if (!todo.title) {
            return res.status(422).json({
                error: 'The field title is required.'
            })
        }
        // 3. 数据验证通过,将数据存储到db中
        const db = await getDb()
        const lastTo = db.todos[db.todos.length - 1]
        todo.id = lastTo ? lastTo.id + 1 : 1
        db.todos.push(todo)
        // 把db重新写入到db.json文件内
        await saveDb(db)
        // 发送响应
        res.status(200).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 => todo.id === Number.parseInt(req.params.id))

        if(!ret){
            return res.status(404).end()
        }
        Object.assign(ret, todo) //把todo内的属性内容复制到ret内,返回ret对象。如果有同名属性的话,后面的属性值会覆盖前面的属性值。具体可看ES6官方文档
        await saveDb(db)
        res.status(200).json(ret)
    } catch (err) {
        res.status(500).json({
            error: err.message
        })
    }
    res.send('patch /todos')
})

/* 删除任务 */
app.delete('/todos/:id', async (req, res) => {
    try {
        //1. 拿到要删除的任务的id
        const todoId = Number.parseInt(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) //从索引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')
})

效果

  • 查询任务列表

注意查看返回的状态码(200)

  • 根据ID查询单个任务

注意查看返回的状态码(200

  • 添加任务

注意查看返回的状态码(200)

  • 修改任务

注意查看返回的状态码(200)

  • 删除任务

注意查看返回的状态码(204)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值