【问题标题】:Handling data existence validation in ExpressJS service layer or controller在 ExpressJS 服务层或控制器中处理数据存在验证
【发布时间】:2020-07-01 08:52:28
【问题描述】:

我在一个中型网站上工作,我认为我需要编写具有更好项目结构的更易维护的代码。

我发现 this article 和其他一些人描述了关于 3 层架构的基本相同的想法

我发现它很棒,因为我以前没有使用过服务层,它有助于 DRY 代码 但这篇文章没有包含任何关于验证以及应该如何处理的内容。尤其是在对数据库进行验证时(例如检查资源是否存在)

我应该在服务层进行验证还是编写验证中间件(这将需要访问数据库,我认为这违反了所描述的模式)

例如,我最终得到了两个 API 端点,网站用户可以在其中更新和删除他们已经添加的 DeliveryAdddress。正如您在下面看到的,服务层中的验证导致路由具有重复的代码来处理 HTTP 响应。

我的路线文件

router.put('/delivery-addresse/:id', DeliveryAddressesController.update);
router.delete('/delivery-addresses/:id', DeliveryAddressesController.remove);

DeliveryAddressesController

    async update(req, res){
        try {
            ....
            await AddressesService.updateDeliveryAddress(userId, address);
            ....
        } catch(error){
            
            if (error instanceof ValidationError){
                if (error.name === 'NO_SUCH_ADDRESS'){
                    return res.status(404).json(error);
                }
            }
            ....
        }
    },

    async remove(req, res){
        try {
            ...
            await AddressesService.removeDeliveryAddress(userId, addressId);
            ....
        } catch(error){

            if (error instanceof ValidationError){
                if (error.name === 'NO_SUCH_ADDRESS'){
                    return res.status(404).json(error);
                }
            }
            ....
        }
    },

选项

我可以想到这些选项,但不确定它们是否好,哪个好。

  1. 控制器之前的验证中间件(中间件)本身将调用 服务中的验证方法。

    我认为这是一个不错的选择,但也许我 如果我不存储结果,最终会调用多个数据库来获取资源 在req 对象中

  2. 使用 catch 块中的函数来检查任何 ValidationErrors 并做出响应,但这不是一种很好的可读方式。

【问题讨论】:

  • 我认为第二个选项实现很好,如果可读性不好,也可以,但是您将请求保存在数据库中,因为当您定义用于检查记录是否可用的中间件时(如果可用)然后您将执行其他操作,它在您的服务器中承担更多负载,您可以使用中间件进行字段验证,例如如果您正在验证 userID 等字段,addressId 是必需的并且它必须是 mongo id,因此您可以包括这些操作在你的中间件中,,,,,
  • 感谢您指出这一点,我已经使用中间件来检查必填字段和字段的有效性,为了清楚起见,我没有包括该部分。

标签: javascript node.js express


【解决方案1】:

你要问的第一个问题是我应该写什么凭证...中间件层在操作和应用两层之间,很重要你想做什么样的验证...对于例如,如果您希望网络上有两个通信服务,为它建立一个密钥,您需要一个验证器来检查每个服务中的每个密钥。在这种情况下,最好在标头中发送此密钥并在中间件中对其进行验证,但有时您希望评估来自其他服务甚至来自数据库的信息,这需要几个验证步骤。最好在您的服务层中实现它们!我为此建议选项 2 ?

【讨论】:

    猜你喜欢
    • 2014-02-19
    • 2017-10-19
    • 2013-08-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-25
    • 2013-10-06
    相关资源
    最近更新 更多