Mongoose 中间件实践:实现数据验证和预处理

随着现代 Web 应用越来越复杂和庞大,数据处理变得越来越重要。使用 Node.js 和 MongoDB 构建应用程序时,Mongoose 是一个重要的工具。它是一个对象文档映射 (ODM) 库,它允许使用 Node.js 原生 MongoDB 驱动程序的优点,同时加入了额外的功能,如模式验证、中间件等。

在本文中,我将向您介绍使用 Mongoose 中间件的基础知识,并展示如何实现数据验证和预处理,从而获得更好的数据质量和更简洁的代码。

Mongoose 中间件

Mongoose 中间件是在执行某个操作之前或之后自动执行的函数。中间件提供了一种强大的方式来处理数据,例如更新、删除、查找等,并在必要时执行一些额外的逻辑。它们可以用于将业务逻辑与数据访问分离开来,并可重用和测试逻辑。

Mongoose 中间件分为四种类型:

  • pre:在指定操作执行之前执行的中间件
  • post:在指定操作执行之后执行的中间件
  • document middleware:作用于文档实例
  • query middleware:作用于查询对象

下面将分别对这些中间件类型进行详细说明。

prepost 中间件

prepost 中间件是基于指定操作类型的。其基本结构如下:

------------------------- -------- ------ -
  -- -- --------- ------ --- ---------
  ------
--

-------------------------- -------- -------- ----- -
  -- -- --------- ----- --- ---------
  ------
--

其中,<OPERATION> 表示需要监听的操作类型,例如 saveupdateOnedeleteOne 等。pre 中间件需要调用 next() 来继续执行操作,而 post 中间件则通过第一个参数获取操作的结果,并调用 next()

例如,下面的代码展示了如何在保存文档之前设置 createdAtupdatedAt 字段:

----- ------ - --- -----------------
  ------ -------
  -------- -------
  ---------- -----
  ---------- ----
--

------------------ -------- ------ -
  ----- --- - --- ------
  -------------- - ---
  -- ----------------- -
    -------------- - ---
  -
  ------
--

----- ----- - ----------------------- -------

文档中间件

文档中间件是作用于单个文档实例的。该类型的中间件有两种:initvalidate

init 中间件在从 MongoDB 中检索文档时自动执行,可用于添加计算字段或触发一些组件的操作。例如,下面的代码展示了如何计算文档的 contentLength

------------------- -------- -- -
  ------------------ - -------------------
--

validate 中间件在调用 validate 方法时自动执行。这个方法用于验证文档的有效性,如果出现错误,则会将其捕获并返回。例如,下面的代码展示了如何验证文档的内容是否至少为 10 个字符:

---------------------- -------- ------ -
  -- -------------------- - --- -
    ----- --- -------------- -- --- -------
  -
  ------
--

查询中间件

查询中间件分为以下四种:

  • count
  • deleteMany
  • deleteOne
  • find
  • findOne
  • findOneAndDelete
  • findOneAndRemove
  • findOneAndUpdate
  • remove
  • update
  • updateMany
  • updateOne

查询中间件用于在查询执行前、执行后或进行验证时添加附加逻辑。它们可以用于记录查询、禁止文档删除或禁止查询某些字段等。

下面的代码展示了如何记录每次查询的开始和结束时间:

------------------ -------- ------ -
  -------------------- ---- --- -------
  ------
--

-------------------- -------- -------- ----- -
  --------------------- ---- --- ------- ---------- -------
  ------
--

实现数据验证和预处理

了解了 Mongoose 中间件的基本类型后,我们可以开始实现数据验证和预处理了。这两个过程非常重要,可以帮助我们保持数据的正确性和一致性,并防止恶意用户绕过我们的验证机制。

数据验证

数据验证是指在将数据发送到数据库之前对其进行检查的过程。Mongoose 内置一些验证器,例如 requiredminmaxdefault 等。但是,通过编写自己的验证器和使用 Mongoose 中间件,我们可以更好地控制数据的验证过程。

----- ------ - --- -----------------
  --------- -
    ----- -------
    --------- -----
    ---------- --- --------- ---- -- -- ----- - -------------
    ---------- ---- --------- ------ -- ------ ---- -- -------------
    ------ ------------------ --------- ---- ------- ---- ------- --- ---------
  --
  ------ -
    ----- -------
    --------- -----
    ------- -----
    ------ ---------------- -------- ----- ---------
  --
  --------- -
    ----- -------
    --------- -----
    --------- --------- ------- -
      ------ ------------ -- -
    -- --------- ---- -- -- ----- - ------------
  -
--

在上面的代码中,我们为 usernameemailpassword 字段添加了一些验证器。这些验证器会在调用 save 方法时自动执行,如果未通过验证,则会抛出错误并返回。

Mongoose 还提供了一个等效的方式来定义自定义验证器:

----- ------ - --- -----------------
  --------- -
    ----- -------
    --------- -----
    --------- -
      ---------- -------- ------- -
        ------ ------------ -- -
      --
      -------- --------- ---- -- -- ----- - -----------
    -
  -
--

在这种情况下,验证器使用对象来定义,其包含 validator 函数和 message 字段。

数据预处理

数据预处理是指在将数据发送到数据库之前对其进行转换或修改的过程。它通常用于添加附加信息、格式化数据或执行一些计算。与数据验证类似,数据预处理可以使用 Mongoose 中间件来实现。

----- ------ - --- -----------------
  ----- -------
  ------ -------
  --------- ------
--

------------------ -------- ------ -
  ------------- - ------------------------------ -----------
  ------
--

在上面的代码中,我们为 save 操作添加了一个 pre 中间件,该中间件使用 bcrypt 库将密码哈希,并将结果更新到数据库中。此功能可用于保护密码,并在用户密码丢失时提供额外的安全性。

综合示例

在本节中,我们将结合数据验证和数据预处理实现一个完整的用户模型。该模型包含以下字段:

  • username: 必需、3-32 个字符、只能包含字母和数字
  • email: 必需、邮件格式、必须唯一
  • password: 必需、至少 8 个字符、自动哈希
----- ------ - -----------------
----- -------- - -------------------

----- ---------- - --

----- ---------- - --- -----------------
  --------- -
    ----- -------
    --------- -----
    ---------- --- --------- ---- -- -- ----- - -------------
    ---------- ---- --------- ------ -- ------ ---- -- -------------
    ------ ------------------ --------- ---- ------- ---- ------- --- ---------
  --
  ------ -
    ----- -------
    --------- -----
    ------- -----
    ------ ---------------- -------- ----- ---------
  --
  --------- -
    ----- -------
    --------- -----
    --------- -
      ---------- -------- ------- -
        ------ ------------ -- -
      --
      -------- --------- ---- -- -- ----- - -----------
    -
  -
--

---------------------- -------- ------ -
  ------------- - ------------------------------ -----------
  ------
--

----- ---- - ---------------------- -----------

-------------- - ----

在上面的代码中,我们使用 bcrypt 哈希算法自动将密码哈希,并通过 Mongoose 中间件来实现数据验证和预处理。然后,我们将模型导出为一个 Node.js 模块。

我们可以像下面这样使用这个模型:

----- ---- - ------------------------

----- ---- - --- ------
  --------- --------
  ------ --------------------
  --------- ----------
--

-----------
  -------- -- -
    ----------------- ---------
  --
  ------------ -- -
    -------------------- -------- ------- ------------
  --

在上面的代码中,我们导入了 User 模型,并用默认的值创建了一个用户。然后,我们可以调用 save 方法将用户保存到数据库。

结论

Mongoose 中间件是使 Node.js 和 MongoDB 应用程序更加强大和可扩展的重要组成部分。通过使用它们,我们可以实现数据验证和预处理,并通过这些逻辑来提高数据质量和减少代码冗余。

本文介绍了 Mongoose 中间件的不同类型,并提供了使用数据验证和预处理的示例代码。希望这些示例能够帮助你更好地了解 Mongoose 中间件,并对如何构建更好的应用程序有所帮助。

来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/672c78b4ddd3a70eb6d849a1