## What — 一覧APIは全件を返さない
ページネーションは、一覧APIが結果を**決まった件数ずつ区切って返す仕組み**。
何万件ものデータを1レスポンスに詰めるとサーバーも通信も耐えられないので、「どこから・何件」をクエリパラメータで指定させる。
方式は2つあり、**どちらを使うかはAPI提供側が決める**。利用者に選択権はなく、ドキュメントとレスポンスを見て読み分ける。
| 方式 | パラメータの見た目 | 次のページの取り方 |
| --- | --- | --- |
| offset型 | `?page=2&per_page=30` や `?limit=30&offset=60` | ページ番号・開始位置を自分で増やす |
| cursor型 | `?cursor=eyJpZCI6...` や `?after=abc123` | レスポンスに入っている「しおり」をそのまま次のリクエストに渡す |
**判定基準はレスポンスの中身**。`next` や `cursor` のトークンが返ってくれば cursor型、無ければ番号を自分で計算する offset型。
## How — 終了条件までがワンセット
GitHub の Issue 一覧を2ページ目から30件取る例(offset型)。
```bash
curl "https://api.github.com/repos/golang/go/issues?per_page=30&page=2"
```
全件が欲しいときはループになる。止まる条件は2つだけ。
- **空配列が返ってきたら終わり**(offset型)
- **次のしおりが返ってこなくなったら終わり**(cursor型)
## 落とし穴
- **1回のレスポンスで全件来ていると思い込む**。多くのAPIはパラメータ無指定でも黙って30件などに切っている。「なぜか件数が足りない」の原因はたいていこれ
- **offset型はループ中のデータ増減でページがズレる**。取得中に先頭へ1件増えると、次ページに同じものが重複して現れたり、1件取りこぼしたりする。このズレを「しおり」で防ぐのが cursor型が生まれた理由
## 関連
- [[API]] — API まわりの地図
- [[クエリパラメータ]] — `?key=value` の読み方はこちら
- [[レートリミット]] — 全件ループで次に踏む壁