🌍 译介 · 编译自 Nordic APIs

API 分页完全指南:从 Offset 到 Seek 的取舍

大数据时代,一次查询可能返回上亿条结果,全量返回既拖慢响应又压垮带宽。API 分页是控制返回规模、保障性能的关键手段。本文编译自 Nordic APIs(2019-10-17 首发,2023-05-30 更新),讲清分页是什么,对比 Offset / Keyset / Seek 三种主流方案的优劣,并给出 REST API 中接入分页链接与 Spotify 实战。

📅 更新于 2026-07-23 ⏱ 约 6 分钟阅读 🏷 译介
免费试用 YesApi Pro 查看全部定价 →
🌐本文由 YesApi Pro 团队编译Nordic APIs 的文章《Everything You Need to Know About API Pagination》,原作者 Nordic APIs(原文发布于 2019-10-17(更新 2023-05-30))。版权归原作者所有,内容仅供学习参考。查看英文原文 →
📌 核心结论
分页把海量结果切成可控的「页」,避免一次返回压垮带宽与数据库。Offset 最简单但有深翻页与页面漂移问题;Keyset 用上一页的过滤值翻页、顺序稳定;Seek(after_id)更稳健、与过滤解耦,但自定义排序较难。优先用 Keyset/Seek,分页链接遵循 self/first/prev/next/last 约定。
📑 本文目录
  1. 什么是分页
  2. 方式一:Offset 偏移分页
  3. 方式二:Keyset 键集分页
  4. 方式三:Seek 分页
  5. 在 REST API 中接入分页链接
  6. 实战:Spotify API 分页
  7. 总结与最佳实践
01

一、什么是分页

分页(Pagination)原指网页/图集底部「第几页」的序数编号,把内容拆成一段段。API 分页就是把这个原则用到接口设计上:面对可能返回百万甚至上亿条结果的密集查询,如果不加限制,对 API 的带宽与算力都是无底洞。分页的作用,就是把返回结果的数量限制住,让网络流量保持在可控范围。

02

二、方式一:Offset 偏移分页

Offset 分页是最简单的实现:用 limitoffset 两个参数。它在 SQL 系应用里特别流行,因为 SQL 的 SELECT 本身就带 LIMITOFFSET

GET /items?limit=20&offset=100

优点:几乎零编码;服务端无状态;配合自定义 sort_by 也能用。缺点:① 偏移值很大时性能差——offset=1000000 意味数据库要先扫过 100 万行再丢弃;② 新增数据会引发页面漂移(page drift):先查 offset=0&limit=15,插入 10 条后再查同样的参数,只会返回 5 条(因为新数据把偏移顶回了 10 位),客户端一脸懵。

03

三、方式二:Keyset 键集分页

Keyset 分页用「上一页最后一个结果的过滤值」来定位下一页。比如:先取最新 20 条 GET /items?limit=20,翻页时用上一页最小创建时间做过滤器 GET /items?limit=20&created:lte:2019-01-20T00:00:00

优点:不需要额外后端逻辑,只需一个 limit 参数;顺序稳定——即便中途新增数据,排序也不乱;深翻页同样流畅。代价是它和具体的过滤字段耦合,客户端得知道那个键值。

04

四、方式三:Seek 分页

Seek 是 Keyset 的进阶版:引入 after_id / before_id,把「过滤条件」与「分页」解耦,用更稳定的唯一标识翻页。例如 GET /items?limit=20&after_id=20 取下一页。它本质上就是一句 SELECT * FROM Items WHERE Id > 20 LIMIT 20

优点:过滤逻辑与分页逻辑解耦;顺序稳定;深翻页流畅。缺点:① 后端资源消耗比 Offset/Keyset 略高;② 若某条数据被删,after_id 指向的 id 可能已失效。注意:Seek 难以做自定义排序——比如想按邮箱排序,后端得先查邮箱对应 id,再拿 id 当 WHERE 值二次查询,多一趟往返。

05

五、在 REST API 中接入分页链接

分页不只是后端逻辑,还要让客户端「能逛」。推荐用 HAL(Hypertext Application Language)让 API 可发现:在响应里带 _links,包含 self / first / prev / next / last。这几个名字被广大 API 开发者通用,用它们能让你的接口和其他 API 保持一致。

示例响应片段:"_links": {"self":".../user?page=3","first":".../user","prev":".../user?page=2","next":".../user?page=4","last":".../user?page=133"},再附 counttotal。借助 HATEOAS 库(如 PHP 的 PaginatedRepresentation),把 page/limit 当作查询参数,即可快速产出带翻页链接的列表接口。

06

六、实战:Spotify API 分页

公开 API 普遍采用分页。以 Spotify 取某艺人专辑为例:GET /v1/artists/{id}/albums?include_groups=album&limit=10limit 限制返回 10 张;再用 offset=10 取接下来 10 张。这种「limit + offset」组合简单直观,是 Web API 分页的范本——参考它来设计你的服务,用户就能在复杂数据上顺畅翻页。

07

七、总结与最佳实践

分页随 API 复杂度上升只会更重要。三种主流方案:Offset 最简单,但有深翻页性能差、页面漂移的短板;Keyset 更稳健,却与页面结果强耦合;Seek 最稳健(新增数据顺序仍稳定),但后端实现更复杂、删数据可能错位。

经验法则:数据量小、需随意跳页时用 Offset;追求顺序稳定与性能用 Keyset/Seek;分页链接务必遵循 self/first/prev/next/last 约定,并配合文档讲清每个参数的含义与边界情况。

译者实战注 落地建议与延伸

需要快速落地?

YesApi Pro 私有部署、源码交付、当天上线,帮您把方案变为现实。

立即预约演示 →

常见问题

数据量小、需要随意跳到任意页时用 Offset 最省事;追求深翻页性能与顺序稳定用 Keyset/Seek,避免扫描百万行和页面漂移。

Offset 分页在两次查询间插入新数据,会让同一 offset 对应的实际数据前移,返回数量变少、客户端错乱;Keyset/Seek 用锚点翻页可规避。

通用约定是 self / first / prev / next / last,配合 count/total,客户端据此翻页,和其他 API 保持一致、降低接入成本。

YesApi Pro 开放平台支持列表接口的分页与过滤参数,网关层统一处理请求并返回规范分页元数据,配合限流与监控,保证大数据量下接口依旧稳定。
📚

继续阅读