使用 mongoose 和express进行 CRUD 操作

问题描述 投票:0回答:3

我正在使用 mongoose 创建一个 Express 应用程序,目的是将其连接到前端的 React。

我在下面列出了一些客户控制器的 CRUD 操作,但这种方法有一些我不喜欢的地方。

  1. 当将
    Customer.findById
    与未找到的有效 ObjectID 一起使用时,它会返回
    null
    以及 200 响应代码。 如果没有找到客户,我希望返回 404。 我意识到我可以将
    catch
    响应更改为 404,但我希望进行一些通用错误处理,以防服务器在请求期间出现故障或提供了无效的 ObjectId,这将我带到下一个项目。
  2. 如果我提供无效的 ObjectId,我想提供一些有意义的消息,500 是正确的响应代码吗?
  3. 错误处理:我是否以正确的方式返回错误?当前错误返回带有错误消息的字符串。我应该返回 JSON 吗?例如
    res.status(500).json({error: error.message)
    。 我计划连接它来做出反应(我仍在学习),并且我认为 UI 需要向用户显示这些消息?
  4. findById
    getCustomerById
    updateCustomer
    deleteCustomer
    中重复。 我觉得这是不好的做法,必须有更简化的方法吗?
  5. 我想要一个函数来验证 ObjectId 是否有效。我知道我可以使用
    routes
    来做到这一点,但我不确定检查有效 id 是否应该在
    router.params
    文件中,因为它看起来像是
    routes
    应该处理的事情?请参阅下面我所做的另一个项目的路线示例。
    
    
  6. 根据上述内容,改进我的代码的最佳实践和建议方法是什么? 我已经阅读了 mongoose、mozilla 和 stackoverflow Q&A 的文档,但他们似乎没有解决这些问题(至少我找不到它)。

我确实在寻求一些指导或验证,以确定我所做的事情是正确还是错误。

customer.controller.js

controller

Router.params 示例

这是一个路线文件(与我当前的应用程序无关),并作为我过去如何使用 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

	
javascript node.js mongodb express mongoose
3个回答
3
投票

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;

作为处理者

在您的索引/服务器文件中

constPrettyError = require('pretty-error') const pe = new PrettyError() const errorHandler = (err, req, res, next) => { if (process.env.NODE_ENV !== 'test') { console.log(pe.render(err)) } return res .status(err.status || 500) .json({ error: { message: err.message || 'oops something went wrong' } }) } module.exports = errorHandler

然后在你的处理程序中

app.use(errorHandler)

举个例子

} catch (err) { next(err); }

另请注意,如果您愿意,您也可以自定义此错误处理程序以根据状态切换大小写(或对象)自定义错误

if (!artist) next({ message: "Artist not found" ,status:404 });

然后就

const errorHandler = (err, req, res, next) => { if (process.env.NODE_ENV !== 'test') { console.log(pe.render(err)) } const messagePerStatus = { 404: 'not found', 401: 'no authorization' } const message = messagePerStatus[err.status] return res .status(err.status || 500) .json({ error: { message: message || err.message || 'oops something went wrong' } }) }



0
投票

创建自定义错误类

AppError.js

if (!artist) next({status:404 });

创建错误处理中间件

错误.js

class AppError extends Error { constructor(statusCode, message) { super(); // super(message); this.statusCode = statusCode || 500 ; this.message = message || "Error Something went wrong"; } } module.exports = AppError;

创建一个中间件来验证对象ID

validateObjectId.js

const AppError = require("../helpers/appError"); const errors = (err, req, res, next) => { // console.log(err); let error = { ...err }; error.statusCode = error.statusCode; error.message = error.message; res.status(error.statusCode).json({ statusCode: err.statusCode, message: err.message, }); }; exports.errors = errors;

在你的app.js中

const mongoose = require("mongoose"); const AppError = require("appError"); module.exports = function (req, res, next) { const { _id } = req.params; if (_id && !mongoose.Types.ObjectId.isValid(_id)) { throw new AppError(422, "Invalid ID field in params"); } next(); };

在你的路线文件中

const { errors } = require("errors"); // At the end of all middlewares // Error Handler Middleware app.use(errors);

现在关于重复 findById 方法,我没有看到任何不好的地方,因为它特定于数据库调用,您仍然可以在模型本身上引入静态方法或在 cntroller 上创建单个方法,但仍然需要检查它是否返回找到的对象或不,并处理该错误。


0
投票
	
© www.soinside.com 2019 - 2024. All rights reserved.