【发布时间】:2021-12-30 21:50:13
【问题描述】:
我正在使用 mongoose 创建一个快速应用程序,目的是将其连接到前端的 React。
我在下面为 客户控制器 列出了一些 CRUD 操作,但我不喜欢这种方法。
- 当使用
Customer.findById和未找到的有效 ObjectID 时,它会返回带有 200 响应代码的null。如果没有找到客户,我希望它返回 404。我意识到我可以将catch响应更改为 404,但我希望进行一些通用错误处理,以防服务器在请求期间出现故障或提供了无效的 ObjectId,这将我带到下一个项目。 - 如果我提供了无效的 ObjectId,我想提供一些有意义的消息,500 是正确的响应代码吗?
- 错误处理:我是否以正确的方式返回错误?当前错误返回带有错误消息的字符串。我应该返回 JSON 吗?例如
res.status(500).json({error: error.message)。我计划连接它以做出反应(我仍在学习),并且我认为 UI 需要向用户显示这些消息? -
findById在getCustomerById、updateCustomer和deleteCustomer中重复出现。我觉得这是不好的做法,必须有更精简的方法? - 我想要一个函数来验证 ObjectId 是否有效。我知道我可以做到这一点是使用
router.params的routes,但我不确定检查有效ID 是否应该在routes文件中,因为看起来controller应该处理?请参阅下面我做的另一个项目的路线示例。
根据上述情况,改进我的代码的最佳做法和建议方法是什么? 我已经阅读了来自 mongoose、mozilla 和 stackoverflow Q&A 的文档,但它们似乎没有解决这些问题(至少我找不到)。
我真的在接受一些指导或验证我所做的事情是正确还是错误。
customer.controller.js
const Customer = require("../models/customer.model");
exports.getCustomers = async (req, res) => {
try {
const customers = await Customer.find();
res.status(200).json(customers);
} catch (error) {
res.status(500).send(error.message);
}
};
exports.getCustomerById = async (req, res) => {
try {
const customer = await Customer.findById(req.params.id);
res.status(200).json(customer);
} catch (error) {
res.status(500).send(error.message);
}
};
exports.addCustomer = async (req, res) => {
try {
const customer = new Customer(req.body);
await customer.save().then(res.status(201).json(customer));
} catch (error) {
res.status(500).send(error.message);
}
};
exports.updateCustomer = async (req, res) => {
try {
const customer = await Customer.findById(req.params.id);
Object.assign(customer, req.body);
customer.save();
res.status(200).json(customer);
} catch (error) {
res.status(500).send(error.message);
}
};
exports.deleteCustomer = async (req, res) => {
try {
const customer = await Customer.findById(req.params.id);
await customer.remove();
res.status(200).json(customer);
} catch (error) {
res.status(500).send(error.message);
}
};
Router.params 示例
这是一个路由文件(与我当前的应用程序无关),作为我过去如何使用router.params 的示例提供。
const express = require("express");
const router = express.Router();
const mongoose = require("mongoose");
const Artist = require("../models/Artist");
const loginRequired = require("../middleware/loginRequired");
const {
getArtists,
addArtist,
getArtistById,
updateArtist,
deleteArtist,
} = require("../controllers/artistController");
router
.route("/")
.get(loginRequired, getArtists) // Get all artists
.post(loginRequired, addArtist); // Create a new artist
router
.route("/:id")
.get(loginRequired, getArtistById) // Get an artist by their id
.put(loginRequired, updateArtist) // Update an artist by their id
.delete(loginRequired, deleteArtist); // Delete an artist by their id
router.param("id", async (req, res, next, id) => {
// Check if the id is a valid Object Id
if (mongoose.isValidObjectId(id)) {
// Check to see if artist with valid id exists
const artist = await Artist.findOne({ _id: id });
if (!artist) res.status(400).json({ errors: "Artist not found" });
res.locals.artist = artist;
res.locals.artistId = id;
next();
} else {
res.status(400).json({ errors: "not a valid object Id" });
}
});
module.exports = router;
【问题讨论】:
-
你得到了一个
ObjectId的字符串值——使用本机NodeJS 驱动程序的ObjectId.isValid(id)方法(或Mongoose 中的类似方法)检查该值是否有效。如果无效,则发送res.status(404).send({ message: "the provided id is not valid" })(在这种情况下,500的响应状态代码不正确;它用于不可恢复的服务器端错误)。如果是有效的id,就可以使用它进行数据库操作;例如读取具有该 ID 的文档。如果您期望现有文档但未找到该文档,请发送相同的404响应。
标签: javascript node.js mongodb express mongoose