接口设计
- 创建文章
// POST 请求:/articles // 请求体: { "article": { "title": "How to train your dragon", "description": "Ever wonder how?", "body": "You have to believe", "tagList": ["reactjs", "angularjs", "dragons"] } } // 响应状态码:201 // 响应数据: { "article": { "_id": 123, "title": "How to train your dragon", "description": "Ever wonder how?", "body": "It takes a Jacobian", "tagList": ["dragons", "training"], "createdAt": "2016-02-18T03:22:56.637Z", "updatedAt": "2016-02-18T03:48:35.824Z" } }
- 获取文章列表
// GET 请求:/articles // 请求参数(Query):_page:页码、_size:每页大小 // 响应状态码:201 // 响应数据: { "articles": [ { "_id": "how-to-train-your-dragon", "title": "How to train your dragon", "description": "Ever wonder how?", "body": "It takes a Jacobian", "tagList": ["dragons", "training"], "createdAt": "2016-02-18T03:22:56.637Z", "updatedAt": "2016-02-18T03:48:35.824Z" }, { "_id": "how-to-train-your-dragon-2", "title": "How to train your dragon 2", "description": "So toothless", "body": "It a dragon", "tagList": ["dragons", "training"], "createdAt": "2016-02-18T03:22:56.637Z", "updatedAt": "2016-02-18T03:48:35.824Z" } ], "articlesCount": 2 }
- 获取单个文章
// GET 请求:/articles/:id // 响应状态码:201 // 响应数据: { "article": { "_id": "dsa7dsa", "title": "How to train your dragon", "description": "Ever wonder how?", "body": "It takes a Jacobian", "tagList": ["dragons", "training"], "createdAt": "2016-02-18T03:22:56.637Z", "updatedAt": "2016-02-18T03:48:35.824Z" } }
- 更新文章
// PATCH 请求:/articles/:id // 请求体: { "article": { "title": "Did you train your dragon?" } } // 响应状态码:201 // 响应数据: { "article": { "_id": 123, "title": "How to train your dragon", "description": "Ever wonder how?", "body": "It takes a Jacobian", "tagList": ["dragons", "training"], "createdAt": "2016-02-18T03:22:56.637Z", "updatedAt": "2016-02-18T03:48:35.824Z" } }
- 删除文章
// DELETE 请求:/articles/:id // 响应状态码:201 // 响应数据: { }
接口服务实现
const express = require('express')
const { MongoClient, ObjectID } = require('mongodb')
const dbClient = new MongoClient('mongodb://localhost:27017')
const app = express()
// 配置解析请求体数据 application/json,会把解析到的请求体数据放到 req.body 中
// 注意:一定要在使用之前就挂载这个中间件
app.use(express.json())
app.get('/', (req, res) => res.send('Hello World!'))
// 创建文章
app.post('/articles', async (req, res, next) => {
try {
// 1. 获取客户端表单数据
const { article } = req.body
// 2. 数据验证
if (!article || !article.title || !article.description || !article.body) {
return res.status(422).json({ error: '请求参数不符合规则要求' })
}
// 3. 把验证通过的数据插入数据库中
// 成功 -> 发送成功响应
// 失败 -> 发送失败响应
await dbClient.connect()
const collection = dbClient.db('test').collection('articles')
article.createdAt = new Date()
article.updatedAt = new Date()
const ret = await collection.insertOne(article)
article._id = ret.insertedId
res.status(201).json({ article })
} catch (err) {
// 由错误处理中间件统一处理
next(err)
}
})
// 获取文章列表
app.get('/articles', async (req, res, next) => {
try {
let { _page = 1, _size = 10 } = req.query
_page = Number.parseInt(_page)
_size = Number.parseInt(_size)
await dbClient.connect()
const collection = dbClient.db('test').collection('articles')
const ret = await collection
.find() // 查询数据
.skip((_page - 1) * _size) // 跳过多少条 10 1 0 2 10 3 20 n
.limit(_size) // 拿多少条
const articles = await ret.toArray()
const articlesCount = await collection.countDocuments()
res.status(200).json({ articles, articlesCount })
} catch (err) {
next(err)
}
})
// 获取单个文章
app.get('/articles/:id', async (req, res, next) => {
try {
await dbClient.connect()
const collection = dbClient.db('test').collection('articles')
const article = await collection.findOne({ _id: ObjectID(req.params.id) })
res.status(200).json({ article })
} catch (err) {
next(err)
}
})
// 更新文章
app.patch('/articles/:id', async (req, res, next) => {
try {
await dbClient.connect()
const collection = dbClient.db('test').collection('articles')
await collection.updateOne({ _id: ObjectID(req.params.id) }, { $set: req.body.article })
// req.body.article 在更新后会被变更为更新结果的状态信息
// 查询更新后的数据(仅匹配 _id 可以直接简写为传参)
const article = await collection.findOne({ _id: ObjectID(req.params.id) })
res.status(201).json({ article })
} catch (err) {
next(err)
}
})
// 删除文章
app.delete('/articles/:id', async (req, res, next) => {
try {
await dbClient.connect()
const collection = dbClient.db('test').collection('articles')
await collection.deleteOne({ _id: ObjectID(req.params.id) })
res.status(204).json({})
} catch (err) {
next(err)
}
})
// 错误处理中间件,在此之前所有路由中调用 next(err) 都会进入这里
// 注意:必须具备 4 个参数才会被标识为错误处理中间件
app.use((err, req, res, next) => res.status(500).json({ error: err.message }))
app.listen(3000, () => console.log('Example app listening at http://localhost:3000 ......'))
代码附件下载
打赏作者
您的打赏是我前进的动力
微信
支付宝
MongoDB👉 在 Node 中操作 MongoDB
上一篇
评论