Why paginate
A listing can have thousands of items. Returning them all is slow and expensive. The standard solution is to expose parameters in the query string that the client combines to request exactly what it needs.
Filtering
Filtering reduces the collection to those that meet a condition:
// GET /products?category=books
let list = products;
if (req.query.category) {
list = list.filter((p) => p.category === req.query.category);
}
Sorting
sort indicates the field, with a - in front for descending (?sort=-price).
The comparator must return 0 on ties (otherwise the order becomes
unstable) and work the same with numbers and with text:
// GET /products?sort=price or ?sort=-price (descending)
if (req.query.sort) {
const desc = req.query.sort.startsWith("-");
const field = desc ? req.query.sort.slice(1) : req.query.sort;
list = [...list].sort((a, b) => {
if (a[field] < b[field]) return desc ? 1 : -1;
if (a[field] > b[field]) return desc ? -1 : 1;
return 0; // tie: they keep their order
});
}
Pagination
With page (page, starting at 1) and limit (page size) you compute the
slice of the array with slice:
// GET /products?page=2&limit=10
const page = Number(req.query.page) || 1;
const limit = Number(req.query.limit) || 10;
const start = (page - 1) * limit;
const pageItems = list.slice(start, start + limit);
res.json({ page, limit, total: list.length, data: pageItems });
The usual order is: filter → sort → paginate. This way you paginate over the already filtered and sorted result.