Коли йдеться про масштабовані додатки, сторінкування великих наборів даних є надзвичайно важливим. У цьому блозі я розгляну, як побудувати Feed API зі сторінкуванням, натхненний тим, як Tinder структурує своє API для безперебійного користувацького досвіду. Також я поясню основні концепції, такі як функціональність skip
-limit
у MongoDB, і поділюсь прикладом реалізації.
Що таке сторінкування?
Сторінкування означає розділення набору даних на менші, зручніші частини (сторінки), які можна отримувати поступово. Це покращує продуктивність і підвищує зручність користувацького досвіду, особливо при роботі з великими наборами даних.
Наприклад:
- Сторінка 1: Записи 1–10
- Сторінка 2: Записи 11–20
У MongoDB сторінкування реалізується за допомогою функцій skip
та limit
.
Як працює Feed API у Tinder
API стрічки Tinder зосереджено на показі користувачам профілів, з якими вони ще не взаємодіяли. Воно виключає з'єднані профілі (надіслані або отримані запити) і використовує сторінкування для ефективного завантаження профілів. Ми реалізуємо подібну логіку для нашого Feed API.
Розуміння skip
та limit
у MongoDB
skip(n)
: Пропускає першіn
документів у результатах запиту.limit(m)
: Обмежує результат першимиm
документами після пропуску.
Приклад запиту:
User.find().skip(10).limit(10);
Це отримує другу сторінку користувачів (записи 11–20), коли розмір сторінки — 10.
Маршрут: /feed
Router.get("/feed", userAuth, async (req, res) => {
try {
const loggedInUser = req.user; // Автентифікований користувач
const page = parseInt(req.query.page) || 1; // За замовчуванням сторінка 1
let limit = ParseInt(req.params.limit) || 10;
limit = limit > 50 ? 50 : limit; const skip = (page - 1) * limit; // Обчислюємо кількість документів для пропуску
// Отримуємо всі запити на з'єднання (надіслані + отримані)
const connectionRequests = await Request.find({
$or: [
{ fromUsrId: loggedInUser._id },
{ toUserId: loggedInUser._id }
]
}).select("fromUserId toUserId"); // Створюємо набір користувачів, яких слід приховати з стрічки
const hideUsersFromFeed = new Set();
connectionRequests.forEach((req) => {
hideUsersFromFeed.add(req.fromUserId.toString());
hideUsersFromFeed.add(req.toUserId.toString());
}); // Отримуємо користувачів зі сторінкою, виключаючи прихованих і автентифікованого користувача
const users = await User.find({
$and: [
{ _id: { $nin: Array.from(hideUsersFromFeed) } },
{ _id: { $ne: loggedInUser._id } }
]
})
.select(USER_SAFE_DATA) // Обираємо безпечні дані користувача
.skip(skip) // Пропускаємо документи
.limit(limit); // Обмежуємо набір результатів
res.send(users); // Відправляємо пагінованих користувачів як відповідь
} catch (err) {
res.status(400).json({ message: err.message }); // Обробка помилок
}
});
Пояснення
- Параметри:
page
: Поточний номер сторінки (за замовчуванням — 1).limit
: Кількість записів на сторінку (за замовчуванням — 10).
- Логіка пропуску:
(page - 1) * limit
: Обчислює, скільки записів потрібно пропустити в залежності від поточної сторінки.
- Фільтрація користувачів:
- Отримуємо всі запити на з'єднання за участі автентифікованого користувача.
- Створюємо набір користувачів, яких потрібно виключити зі стрічки (з'єднані користувачі та автентифікований користувач).
- Отримання даних для стрічки:
- Використовуємо
$nin
для виключення прихованих користувачів. - Використовуємо сторінкування за допомогою
skip
таlimit
.
- Обробка помилок:
- Повертаємо статус
400
з повідомленням про помилку, якщо щось пішло не так.
Тестування API
Ви можете протестувати API за допомогою інструментів, таких як Postman або cURL:
Приклад запиту:
GET /feed?page=2&limit=5
Authorization: Bearer
Приклад відповіді:
[
{
"_id": "645f123abc123",
"name": "John Doe",
"age": 25
},
{
"_id": "645f456def456",
"name": "Jane Smith",
"age": 28
}
]
Висновок
Використання skip
та limit
у MongoDB — ефективний спосіб реалізувати сторінкування в ваших API.
У цьому блозі ми створили Feed API, яке виключає конкретних користувачів і використовує сторінкування для ефективного оброблення великих наборів даних.
Цей підхід можна адаптувати для різних випадків використання, не обмежуючись додатками на кшталт Tinder. Експериментуйте з різними стратегіями сторінкування і зробіть ваші API масштабованими та зручними для користувачів!
Перекладено з: Building a Feed API with Pagination in Node.js