05.Express起步——案例

1.案例

通过创建一个简单的CURD接口服务,从而掌握Express的基本用法。
需求:实现对任务清单的CURD接口服务。

  • 查询任务列表
    • GET /todos
  • 根据ID查询单个任务
    • GET /todos/:id
  • 添加任务
    • POST /todos
  • 修改任务
    • PATCH /todos/:id
  • 删除任务
    • DELETE /todos/:id

2.路由设计

路由设计代码,如下:

const express = require('express');
const app = express()

// 查询任务
app.get('/todos', (req, res) => {
    res.send('get /todos')
})
// 查询单个任务
app.get('/todos/:id', (req, res) => {
    //通过req.params来获取动态的路由地址
    res.send(`get /todos/${req.params.id}`)
})
// 添加任务
app.post('/todos', (req, res) => {
    res.send('post /todos')
})
// 修改任务
app.patch('/todos/:id', (req, res) => {
    res.send(`patch /todos/${req.params.id}`)
})
// 删除任务
app.delete('/todos/:id', (req, res) => {
    res.send(`delete /todos/${req.params.id}`)
})

app.listen(3000, () => {
    console.log('server is running!!')
})
复制代码

3.查询任务

3.1 新建一个db.json文件,用来存放数据,内容如下:

{
    "todos": [
        {
            "id": 1,
            "name": "降龙十八掌"
        },
        {
            "id": 2,
            "name": "独孤九剑"
        },
        {
            "id": 3,
            "name": "九阳神功"
        }
    ],
    "users": []
}
复制代码

3.2 修改查询任务的代码,如下

const express = require('express');
const app = express()
const fs = require('fs')

// 查询任务
app.get('/todos', (req, res) => {
    fs.readFile('db.json', 'utf-8', (err, data) => {
        if (err) {
            return res.status(500).json({
                error: err.message
            })
        }
        var db = JSON.parse(data)
        res.status(200).json(db.todos)
    })
})
// 查询单个任务
app.get('/todos/:id', (req, res) => {
    res.send(`get /todos/${req.params.id}`)
})
// 添加任务
app.post('/todos', (req, res) => {
    res.send('post /todos')
})
// 修改任务
app.patch('/todos/:id', (req, res) => {
    res.send(`patch /todos/${req.params.id}`)
})
// 删除任务
app.delete('/todos/:id', (req, res) => {
    res.send(`delete /todos/${req.params.id}`)
})

app.listen(3000, () => {
    console.log('server is running!!')
})

复制代码

思路:通过Nodejs的读文件功能,读取文件,返回的是字符串格式(注意设置成utf-8),然后,将json字符串转成json格式返给客户端。

4.查询单个数据

查询单个任务的代码,如下:

const express = require('express');
const app = express()
const fs = require('fs')

// 查询任务
app.get('/todos', (req, res) => {
    fs.readFile('db.json', 'utf-8', (err, data) => {
        if (err) {
            return res.status(500).json({
                error: err.message
            })
        }
        var db = JSON.parse(data)
        res.status(200).json(db.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
            })
        }
        var db = JSON.parse(data)
        var todo = db.todos.find(todo => todo.id.toString() === req.params.id);
        if (!todo) {
            return res.status(404).json({
                data: 'not found'
            })
        }
        res.status(200).json(todo)
    })
})
// 添加任务
app.post('/todos', (req, res) => {
    res.send('post /todos')
})
// 修改任务
app.patch('/todos/:id', (req, res) => {
    res.send(`patch /todos/${req.params.id}`)
})
// 删除任务
app.delete('/todos/:id', (req, res) => {
    res.send(`delete /todos/${req.params.id}`)
})

app.listen(3000, () => {
    console.log('server is running!!')
})
复制代码

思路:和查询全部数据的思路一样,查到全部数据之后,根据传过来的id和读取到的数据进行比较,这里要注意地址栏获取的参数是字符串类型,json数据中的id是number类型,需要转换以下,然后,判断以下是否查到了数据,如果查到了返回该数据,如果没查到返回404,not fount

5.封装db模块

思考:考虑到目前查询全部数据的功能和查询单条数据的功能中,获取数据的代码都一样,我们可以对他们进行封装以下。

新建db.js,内容如下:

const fs = require('fs');
const { promisify } = require('util');
const path = require('path')

const readFile = promisify(fs.readFile)
const dbPath = path.join(__dirname, './db.json')
exports.getDb = async () => {
    let data = await readFile(dbPath, 'utf8')
    return JSON.parse(data)
}
复制代码
  • promisify: 将异步回调的方法处理成promise

index.js文件,代码修改如下:

const express = require('express');
const app = express()
const fs = require('fs')
const { getDb } = require('./db')

// 查询任务
app.get('/todos', async (req, res) => {
    try {
        let db = await getDb();
        res.status(200).json(db.todos);
    } catch (err) {
        res.status(500).json({
            error: err.message
        })
    }
    // fs.readFile('db.json', 'utf-8', (err, data) => {
    //     if (err) {
    //         return res.status(500).json({
    //             error: err.message
    //         })
    //     }
    //     var db = JSON.parse(data)
    //     res.status(200).json(db.todos)
    // })
})
// 查询单个任务
app.get('/todos/:id', async (req, res) => {
    try {
        let db = await getDb();
        let todo = db.todos.find(todo => todo.id.toString() === req.params.id);
        if (!todo) {
            return res.status(404).json({
                data: 'not found'
            })
        }
        res.status(200).json(todo)
    } catch {
        res.status(500).json({
            error: err.message
        })
    }
    // fs.readFile('db.json', 'utf-8', (err, data) => {
    //     if (err) {
    //         return res.status(500).json({
    //             error: err.message
    //         })
    //     }
    //     var db = JSON.parse(data)
    //     var todo = db.todos.find(todo => todo.id.toString() === req.params.id);
    //     if (!todo) {
    //         return res.status(404).json({
    //             data: 'not found'
    //         })
    //     }
    //     res.status(200).json(todo)
    // })
})
// 添加任务
app.post('/todos', (req, res) => {
    res.send('post /todos')
})
// 修改任务
app.patch('/todos/:id', (req, res) => {
    res.send(`patch /todos/${req.params.id}`)
})
// 删除任务
app.delete('/todos/:id', (req, res) => {
    res.send(`delete /todos/${req.params.id}`)
})

app.listen(3000, () => {
    console.log('server is running!!')
})

复制代码

通过async和await来获取到异步的数据,然后,通过try..Catch..来捕获异常信息

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享