コレクションを返すエンドポイントは、結果を 制限し形作る 必要があります。3 つの関心事 — ページネーション、フィルタ、ソート — はすべて query string に存在します。
ページネーション: offset vs cursor
Offset (ページベース) — ?page=3&limit=20 または ?offset=40&limit=20。
GET /orders?offset=40&limit=20 HTTP/1.1
単純で任意のページにジャンプできますが、規模が大きいと 2 つの問題があります: OFFSET 100000 はデータベースに 10 万行を走査して捨てさせ (遅い)、リクエスト間で行が挿入/削除されると項目が ずれ、重複や飛ばしが見えます。
Cursor (keyset) — client が最後に見た項目への不透明なポインタを渡します。
GET /orders?limit=20&cursor=eyJpZCI6MTAyMH0 HTTP/1.1
HTTP/1.1 200 OK
{
"data": [ /* 20 orders */ ],
"page": { "next_cursor": "eyJpZCI6MTA0MH0", "has_more": true }
}
server は cursor を WHERE id > 1020 ORDER BY id LIMIT 20 に翻訳します — どの深さでも高速なまま、挿入に対して 安定 なインデックス付きルックアップです。トレードオフ: 「500 ページ目」へのランダムアクセスはできません。
Offset → 小さいデータセット、管理 UI、「ページ N へジャンプ」
Cursor → 大きい/無限フィード、リアルタイムデータ、モバイルのスクロール
GET /orders?status=shipped&min_total=100&sort=-created_at,id HTTP/1.1
status=shipped)。許可するフィールドをホワイトリスト化します。sort param で ソート。- 接頭辞は降順を意味します (-created_at)。安定した順序のためにマルチキーをサポートします。limit に上限 (例: 最大 100) を設け、client が 100 万行を要求できないようにします。これは最も実用的な API 設計質問の 1 つです。ほぼすべてのリストエンドポイントがぶつかり、選択が実際のパフォーマンスに影響するからです。面接官はたいてい offset-vs-cursor のトレードオフ を探ります: どこでも offset ページネーションに手を伸ばす候補者は、OFFSET 1000000 がテーブルを走査する痛みや、無限フィードをスクロールするユーザーが新しい投稿の挿入で同じ投稿を 2 回見る「結果ずれ」バグを味わっていません。Cursor ページネーションはクエリをインデックス付き keyset ルックアップに変えて両方を修正するので、あらゆる大規模 API (Twitter、Stripe、Slack) がフィードにこれを使います。強い答えは運用上のガードレールにも触れます — フィルタ/ソートフィールドのホワイトリスト化 (インデックスのないクエリと injection を避ける) と limit の上限 (データベースを守る) — これが、これらのエンドポイントを production で運用した人と、読んだだけの人を分けます。
ジュニアからシニアまで、詳細な回答付きのIT面接質問ライブラリ。
寄付する