rest api 的(页面,大小)或(限制,偏移量)哪种分页方法更好

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

我搜索了很多堆栈溢出的答案、文章,但无法得到具体的想法,这就是我问这个问题的原因,

参考资料:更好的 RESTful API 的 10 个最佳实践

我只是想知道当我们在rest api中进行分页时应该使用什么, 在 spring 框架中,他们默认提供

(page,size)
来实现 api 中的分页,我认为使用
(page, size)
(limit, offset)
更具有人类可读性并且更有意义,有什么原因 spring 默认提供
(page,size)
而不是比限制,偏移量和许多答案都是为了证明
(limit,offset)
(page,size)
更好。

https://somewhere.com/results?page=1&size=20

https://somewhere.com/results?limit=20&offset=0

java spring rest hyperlink hateoas
5个回答
11
投票

在 Page/PageSize 与 Offset/Limit 中,使用 Page/PageSize 更简单,因为所有 Page 的 PageSize 都是相同的;但是,如果您针对特定范围的项目,则使用 Offset/Limit 可以为您提供更精确的数据,并且您无法使用 Page/PageSize 方法来执行此操作。下图展示了两者之间的关系:

enter image description here

在第一个块上,如果您的目标是第 6 项到第 8 项,则您的 PageSize 为 3:

Limit = PageSize = 3
Page = 3 // from the first block above, item 6 to item 8 sits on Page 3
Offset = (Page * PageSize) - PageSize
Offset = (3 * 3) - 3
Offset = 6

在第二个块上,如果您的目标是第 7 项到第 9 项,那么您的 PageSize 再次为 3:

Limit = PageSize = 3
Page = 3.3333 // from the 2nd block, item 7 to item 9 sits exactly in Page = 3.3333, and not in Page = 3
Offset = (Page * PageSize) - PageSize
Offset = (3.3333 * 3) - 3
Offset = 9.9999 - 3
Offset = 7 

在第三个块上,您的目标是第 7 项到第 10 项,因此您的 PageSize = 4:

Limit = PageSize = 4
Page = 2.75 // from the 3rd block, item 7 to item 9 sits exactly in Page = 2.75, and not in Page 3, if the PageSize is 4
Offset = (Page * PageSize) - PageSize
Offset = (2.75 * 4) - 4
Offset = 11 - 4
Offset = 7 

显然,偏移量是目标项目的起始索引,限制是您的目标项目的数量。我只是向您展示这两种方法的关系。


4
投票

如果您不使用 spring,则在代码中使用限制和偏移会更容易一些,例如,您可以将这些值直接传递给 dbms。

对于页面和尺寸,您必须计算偏移和限制值。如果有框架,它会为您完成工作。

但在我看来,没有“最好的方法”。两种解决方案都适用于多种情况。


1
投票

我使用page&limit方法。恕我直言,这些是参数的最佳名称。所以事情会是这样的:

https://somewhere.com/results?page=1&limit=10

我找不到关于“如何做”问题的任何明确答案。


1
投票

我认为限制/大小更好,因为它为客户提供了更多选择。他们可以请求任何结果集。缺点是客户端需要计算偏移量。

页面/大小很诱人,因为它对于个人来说更自然,并且对于客户来说更容易实现。 只要您不需要获得 50 个结果,但忽略其中的前 25 个就可以了。但如果你这样做了——那就太糟糕了。


0
投票

为什么不同时提供两者?

这就是我使用的,带有我的快速代码,非常简化。用户可以选择(更容易理解)

page&size
或(更精确但技术性更强)
limit&offset

router.get('/', async (req, res) => {
  ...
  const DEFAULT_PAGE_SIZE = 20;
  let { limit, offset, page, size } = req.query;
  if (page == null) { 
    limit = size ?? DEFAULT_PAGE_SIZE; 
    offset = (page - 1) * size };  
  } 
  if (limit != null) {
    limit = DEFAULT_PAGE_SIZE;
  }
  if (offset == null) offset = 0;
  ...
  let rows = await db.getAllThings(limit, offset);
  res.json(rows);
});
© www.soinside.com 2019 - 2024. All rights reserved.