api-pagination について
大規模な API データセットのページネーションを実装するための開発スキルです。オフセット、カーソル、キーセット方式に加え、レスポンス形式やクエリ制限も説明します。
主な機能
- 01オフセット・カーソル・キーセット方式
- 02ページネーションレスポンス構造の例
- 03ページサイズ上限の指針
- 04インデックスと件数クエリの実践
活用シーン
- 01商品コレクションのページ分割
- 02無限スクロールフィードの対応
- 03大規模データセットの効率的な提供
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ secondsky/ claude-skills --skill api-paginationインストール後、Claude Code で/api-paginationを入力して読み込まれたか確認します。
詳細
API のページネーション
大規模なデータセットを効率的に処理するための、スケーラブルなページネーション戦略を実装します。
ページネーション戦略
| 戦略 | 最適な用途 | パフォーマンス |
|---|---|---|
| オフセット/リミット | 小規模なデータセット、シンプルな UI | O(n) |
| カーソル | 無限スクロール、リアルタイム | O(1) |
| キーセット | 大規模なデータセット | O(1) |
オフセットページネーション
app.get('/products', async (req, res) => {
const page = parseInt(req.query.page) || 1;
const limit = Math.min(parseInt(req.query.limit) || 20, 100);
const offset = (page - 1) * limit;
const [products, total] = await Promise.all([
Product.find().skip(offset).limit(limit),
Product.countDocuments()
]);
res.json({
data: products,
pagination: {
page,
limit,
total,
totalPages: Math.ceil(total / limit)
}
});
});
カーソルページネーション
app.get('/posts', async (req, res) => {
const limit = 20;
const cursor = req.query.cursor;
const query = cursor
? { _id: { $gt: Buffer.from(cursor, 'base64').toString() } }
: {};
const posts = await Post.find(query).limit(limit + 1);
const hasMore = posts.length > limit;
if (hasMore) posts.pop();
res.json({
data: posts,
nextCursor: hasMore ? Buffer.from(posts[posts.length - 1]._id).toString('base64') : null
});
});
レスポンス形式
{
"data": [...],
"pagination": {
"page": 2,
"limit": 20,
"total": 150,
"totalPages": 8
},
"links": {
"first": "/api/products?page=1",
"prev": "/api/products?page=1",
"next": "/api/products?page=3",
"last": "/api/products?page=8"
}
}
ベストプラクティス
- 妥当な最大値(例:100)を設定します
- 大規模なデータセットにはカーソルページネーションを使用します
- 並べ替えフィールドにインデックスを設定します
- 可能な場合は COUNT クエリを避けます
- ページサイズを無制限にできるようにしないでください
コメント
Markdown 対応