API分页实现 api-pagination

本技能专注于实现高效的API分页策略,包括偏移量分页、游标分页和键集分页,用于处理大型数据集、构建分页端点、实现无限滚动和优化数据库查询。关键词:API分页,高效数据处理,分页策略,数据库优化,无限滚动,分页端点。

后端开发 0 次安装 0 次浏览 更新于 3/8/2026

name: api-pagination description: 使用偏移量、游标和键集策略实现高效的API分页,用于处理大型数据集。适用于构建分页端点、实现无限滚动或优化数据库查询集合。

API分页

实现可扩展的分页策略,以高效处理大型数据集。

分页策略

策略 最佳适用 性能
Offset/Limit 小型数据集,简单UI O(n)
Cursor 无限滚动,实时 O(1)
Keyset 大型数据集 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查询
  • 永远不允许无限制的页面大小