RESTful API 设计中的分页(Pagination)

什么是分页

在 Web 应用程序中,分页是一种将结果分解成若干页面的技术,使用户可以分批查看结果。在 RESTful API 中,分页是将数据分段返回给客户端,以避免一次返回大量数据而导致响应时间太长,甚至导致客户端崩溃。

为什么需要分页

当数据量特别大时,一次性返回所有数据到客户端会对服务器造成巨大的负担,可能会导致系统崩溃,甚至影响其他客户端的使用。此外,客户端也很难处理如此大量的数据,可能需要等待很长时间才能渲染完整个页面。因此,我们需要将数据分页返回以减轻服务器负担和提高客户端性能。

分页的参数

在 RESTful API 中实现分页,需要客户端向服务器传递一些参数。通常,这些参数包括:

  • page:当前页数;
  • size:每个页面的大小(即每个页面返回的数据量)。

例如,我们可以使用以下 URL 将一个资源的前 10 个实例返回:

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

此 URL 表示从第一页开始,每页返回 10 条数据。

分页的响应

在通常的情况下,响应将返回两个组件:数据和元数据。数据是当前页的实例列表,元数据包含有关当前和其他页面的信息。

数据

数据是当前页面的所有实例列表。例如,如果我们请求以下 URL,将返回第 3 页的所有实例:

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

响应将返回这些实例的 JSON 表示形式。例如:

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

元数据

元数据包括以下信息:

  • count:所有实例的数量;
  • pages:总共的页数;
  • next:下一页的 URL;
  • prev:前一页的 URL;
  • self:当前页面的 URL。

例如,我们使用以下 URL 请求第 3 页:

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

响应将返回以下元数据:

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

count 表示所有实例的数量,pages 表示总共的页数,next 表示下一页的 URL,prev 表示上一页的 URL,self 表示当前页面的 URL。

示例代码

下面的示例代码演示了如何在 Node.js / Express 应用程序中实现分页。

安装依赖

我们需要使用 express 和 mongoose 组件来构建应用程序。通过以下命令安装这些模块:

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

创建模型和数据

首先,我们需要创建一个名为 item.js 的模型。这个模型将被使用来操作数据库。

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

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

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

现在,我们假设已经有一些数据存储在库中。我们将使用以下数据来测试分页:

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

创建路由

现在,我们需要创建一个路由,它将根据客户端提供的参数返回所需数量的实例。下面是路由的代码:

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

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

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

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

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

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

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

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

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

这个路由将获取客户端提供的 page 和 size 参数,并使用 MongoDB 的 countDocuments() 方法来计算所有实例的数量。然后它使用 limit() 和 skip() 方法从数据库中获取结果,并将它们放入结果对象中。

如果客户端请求的页面不是第一个,它将在结果对象中包含前一页的 URL。同样,如果客户端请求的页面不是最后一页,它将包含下一页的 URL。

结论

在设计 RESTful API 时,必须考虑到分页的问题。通过将数据分段返回给客户端,可以有效地减轻服务器负担,并提高客户端性能。我们可以使用客户端提供的参数来分页查询数据,并在响应中返回数据和元数据。使用 Node.js 和 Express,分页非常容易实现。

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