分页 API 响应对于高效处理大型数据集至关重要。以下是最常见的策略:
1. 基于偏移量的分页 (SKIP/LIMIT)
- 工作原理: 客户端发送
offset(要跳过的记录数)和limit(要返回的最大记录数)参数。 - 优点: 实现和理解简单。
- 缺点: 对于非常大的偏移量可能效率低下,因为数据库仍必须处理然后丢弃跳过的记录。如果请求之间添加或删除了数据(例如,某个项目可能出现在多个页面上或完全被跳过),则可能导致结果不一致。
- 示例:
/api/items?offset=10&limit=10(获取第 11-20 条记录)
2. 基于游标的分页 (Keyset Pagination)
- 工作原理: 客户端发送一个“游标”(通常是前一页的最后一个项目的 ID 或时间戳),而不是偏移量。然后服务器返回此游标之后的项目。
- 优点: 对于大型数据集更有效,因为它不会重新扫描之前的记录。对于请求之间的数据更改(添加/删除)更健壮,提供更稳定的数据“快照”。
- 缺点: 实现起来可能更复杂。需要一致的排序顺序和唯一的、顺序标识符(或字段组合)作为游标。无法轻松跳转到任意页面编号。
- 示例:
/api/items?after_id=12345&limit=10(获取 ID 为 12345 的项目之后的 10 个项目)
3. 基于页面的分页 (页码/页面大小)
- 工作原理: 客户端发送
page_number和page_size参数。这本质上是基于偏移量的分页的用户友好包装器(offset = (page_number - 1) * page_size)。 - 优点: 对用户来说很直观,允许直接跳转到特定页面编号。
- 缺点: 继承了基于偏移量的分页的低效率和不一致性。
- 示例:
/api/items?page=2&page_size=10(获取 10 条记录的第二页)
实施的关键考虑因素:
- 总数: 决定是否在响应中包含项目的
total_count。这对于“第 1 页,共 10 页”之类的 UI 元素很有用,但对于非常大的数据集,计算它可能会很昂贵。基于游标的分页通常省略此项。 - 排序: 分页几乎总是需要一致的排序顺序才有意义。
- 错误处理: 如果
offset或page_number超出范围会怎样? - 安全性: 确保验证分页参数以防止滥用(例如,极大的
limit值)。 - HATEOAS (超媒体作为应用程序状态引擎): 对于 RESTful API,请考虑在响应中包含指向
next、prev、first和last页面的链接,以指导客户端。