Коли ви створюєте API для сучасних застосунків, користувачі очікують гнучкості в запитах до даних. Фільтрація є однією з найважливіших функцій, яка підвищує зручність використання вашого API. У цьому блозі ми розглянемо базові та розширені техніки фільтрації з використанням Node.js і MongoDB, щоб допомогти вам вивести ваш бекенд на новий рівень.
Що таке фільтрація?
Фільтрація дозволяє клієнтам запитувати конкретні підмножини даних із вашого API на основі певних критеріїв. Наприклад:
- Отримання турів у певному діапазоні цін.
- Вибір користувачів за статусом підписки.
- Пошук продуктів із конкретними тегами.
Завдяки фільтрації ви надаєте користувачам можливість отримувати лише потрібну інформацію, не перевантажуючи сервер і не надсилаючи зайвих даних.
Крок 1: Реалізація базової фільтрації
Базова фільтрація дозволяє клієнтам робити запити за допомогою простих пар ключ-значення. Давайте реалізуємо це в API на Node.js і MongoDB.
Розглянемо кінцеву точку GET /api/v1/tours
, де користувачі можуть фільтрувати тури за такими полями, як duration
, price
або difficulty
.
Приклад запиту:
GET /api/v1/tours?duration=5&difficulty=easy
Цей запит має повертати всі тури з тривалістю (duration
) 5 та складністю (difficulty
) "easy".
Реалізація:
Ось як можна обробити базову фільтрацію у вашому контролері:
try {
// 1. Отримати параметри запиту
const queryObj = { ...req.query };
const excludedFields = ['page', 'sort', 'limit', 'fields'];
// 2. Видалити спеціальні поля (пагінація, сортування тощо)
excludedFields.forEach((el) => delete queryObj[el]);
// 3. Виконати запит
const tours = await Tour.find(queryObj);
res.status(200).json({
status: 'success',
results: tours.length,
data: { tours },
});
} catch (err) {
res.status(400).json({
status: 'fail',
message: err.message,
});
}
};
Крок 2: Розширена фільтрація
Базова фільтрація чудова, але для реальних застосунків часто потрібна більша гнучкість. Розширена фільтрація дозволяє користувачам виконувати такі операції:
- Пошук елементів більше або менше за певне значення.
- Вибір діапазону значень.
- Використання логічних операторів, як-от
AND
іOR
.
Приклад запиту:
GET /api/v1/tours?price[lt]=500&duration[gte]=7
Цей запит має повертати всі тури з ціною (price
) менше 500 і тривалістю (duration
) більше або дорівнює 7.
Реалізація:
Щоб досягти цього, ми перетворимо рядок запиту у сумісні з MongoDB оператори.
const getAllTours = async (req, res) => {
try {
// 1. Отримати параметри запиту
let queryObj = { ...req.query };
const excludedFields = ['page', 'sort', 'limit', 'fields'];
excludedFields.forEach((el) => delete queryObj[el]);
// 2. Розширена фільтрація: заміна операторів
let queryStr = JSON.stringify(queryObj);
queryStr = queryStr.replace(/\b(gte|gt|b/g, (match) => `$${match}`);
// 3. Виконати запит
const tours = await Tour.find(JSON.parse(queryStr));
res.status(200).json({
status: 'success',
results: tours.length,
data: { tours },
});
} catch (err) {
res.status(400).json({
status: 'fail',
message: err.message,
});
}
Найкращі практики для фільтрації
- Санітуйте введення: Завжди перевіряйте та очищуйте параметри запиту, щоб запобігти атакам ін'єкції.
- Встановлюйте обмеження: Уникайте розкриття надто великого обсягу даних, встановлюючи розумні межі для запитів.
- Документуйте ваш API: Чітко пояснюйте, як користувачі можуть використовувати фільтрацію у вашій документації API.
- Ретельно тестуйте: Переконайтеся, що логіка фільтрації працює для всіх крайніх випадків, як-от порожні запити чи некоректні поля.
Висновок
Фільтрація є необхідною функцією будь-якого сучасного API. Реалізуючи як базові, так і розширені техніки фільтрації, ви зможете запропонувати більш потужний і гнучкий інтерфейс для ваших користувачів.
З Node.js і MongoDB можливості безмежні, тож не зупиняйтесь на цьому — продовжуйте досліджувати, як можна вдосконалити та оптимізувати ваш API.
Спробуйте додати фільтрацію у власний проєкт — ваші користувачі будуть вам вдячні!
Перекладено з: Making the API Better: Filtering and Advanced Filtering in Node.js and MongoDB