Хуки Mongoose — своего рода ниндзя-шпионы, работающие вне поля зрения, перехватывая и изменяя операции с данными в ключевых точках. Это невероятно мощные инструменты для добавления пользовательской логики в Mongoose-приложения, но их освоение может быть похоже на взлом секретного кода. Но вам, бесстрашные разработчики, незачем волноваться, ведь эта статья упростит задачу.
Что такое хуки Mongoose?
Хуки — это промежуточные функции, срабатывающие в определенные моменты жизненного цикла Mongoose. Считайте их контрольными точками, позволяющими проверять, изменять или даже прерывать такие операции, как сохранение, обновление или удаление документов. Они бывают двух видов:
- Pre-hooks (предварительные хуки): запускаются перед основной операцией, позволяя манипулировать данными или выполнять валидацию до попадания в базу данных.
- Post-hooks (послеоперационные хуки): запускаются после выполнения основной операции, позволяя реагировать на результат (успех или неудачу) и выполнять такие задачи, как отправка уведомлений или регистрация изменений.
Типы хуков Mongoose
Mongoose предлагает четыре типа хуков, каждый из которых отвечает различным потребностям.
- Хуки для документов: предназначены для отдельных документов и работают с такими методами, как
save
,update
иremove
. - Хуки для запросов: перехватывают и изменяют запросы до того, как они попадают в базу данных. Полезны для добавления предварительных условий или установки ограничений.
- Хуки для агрегирования: подключаются к конвейеру агрегирования, позволяя изменять преобразования данных во время процесса агрегирования.
- Хуки для моделей: запускаются для всей модели. Полезны для глобальных задач, таких как установка временных меток и инициализация значений по умолчанию.
Преимущества использования хуков Mongoose
Вот основные преимущества применения хуков.
- Инкапсулированная логика. Переносите сложную логику из схем моделей в многократно используемые хуки, сохраняя чистоту и удобство обслуживания кода.
- Валидация и безопасность. Выполняйте пользовательские валидации и преобразования данных до того, как они попадут в базу данных, повышая целостность и безопасность данных.
- Автоматизация и уведомления. Запускайте автоматизированные задачи, такие как отправка электронных писем и регистрация изменений на основе операций с данными.
- Расширяемость и плагины. Создавайте многократно используемые плагины на основе хуков для совместного использования функциональности в приложениях.
Хуки в действии
Посмотрим несколько примеров кода, чтобы понять, как работают хуки.
Хук предварительной проверки перед сохранением для хэширования паролей (pre-save hook)
const userSchema = new Schema({
username: String,
password: String,
});
// хук предварительной проверки
userSchema.pre('save', async function (next) {
if (!this.isModified('password')) return next();
const hashedPassword = await bcrypt.hash(this.password, 10);
this.password = hashedPassword;
next();
});
Этот хук проверяет, не изменен ли пароль. Если да, то перед сохранением документа хэширует его с помощью bcrypt
.
Хук для отправки уведомлений об удалении после операции удаления (post-remove hook)
const userSchema = new Schema({
email: String,
});
userSchema.post('remove', function (user) {
// Отправка email-уведомления об удаленном пользователе
sendEmail(user.email, 'Your account has been deleted');
});
Этот хук отправляет уведомление по электронной почте, когда документ пользователя удаляется.
Примеры для Next.js
Хук post-find для преобразования _id в строку
const userSchema = new Schema({
// ... другие поля
});
// вместо 'find' можем также использовать regex
userSchema.post('find', function (docs) {
for (const doc of docs) {
doc._id = doc._id.toString();
}
});
Маршрут API (для Next 12 и более ранних версий)
import User from '../../models/user';
export default async function handler(req, res) {
const users = await User.find();
res.json(users);
}
Маршрут API (для Next 13 и более поздних версий)
import User from '../../models/user';
export async function GET() {
const users = await User.find();
return new Response(
JSON.stringify(users);
)
}
Компонент (app/page.tsx)
import React from 'react';
export default function Page() {
const { data } = useSWR('/api/page', fetcher); // Fetch data using SWR
return (
<ul>
{data?.map((user) => (
<li key={user._id}>{user.name} (ID: {user._id})</li>
))}
</ul>
);
}
Ключевые моменты
Из приведенных примеров можно сделать следующие выводы:
- Хук
post('find')
изменяет все документы, возвращаемыеUser.find()
. - Он преобразует свойство
_id
из ObjectId в строку, что делает его совместимым с компонентами Next.js 13. - Маршруты API обеспечивают получение данных на стороне сервера, где выполняются хуки Mongoose.
- SWR (или любая другая библиотека, помогающая извлекать данные) используется для получения и кэширования данных в компоненте.
Дополнительные соображения
При использовании хуков учитывайте следующие моменты.
- Если нужно изменить отдельные документы перед передачей их компонентам, рассмотрите возможность использования хука предварительного поиска (pre-find hook) или промежуточного программного обеспечения.
- Для сложных преобразований или фильтрации данных можно использовать хуки для запросов или конвейеры агрегирования.
- Всегда тщательно тестируйте хуки, чтобы убедиться в том, что они работают так, как ожидается, и не вызывают непредвиденных побочных эффектов.
Возьмите на заметку
Используя хуки, помните:
- По умолчанию хуки асинхронны. Для обработки асинхронных операций используйте
async/await
или обратные вызовы на основе промисов, напримерnext()
. - Контекст (
this
) хука зависит от его типа. Касательно хуков для документов —this
относится к самому документу. - Можно связать в цепочку несколько pre- или post-хуков для одного и того же события, создавая мощный конвейер пользовательской логики.
Заключение
Хуки Mongoose — это универсальный инструмент, который может раскрыть весь потенциал приложений Mongoose. Экспериментируйте, изучайте и раскрывайте мощь этих ниндзя-шпионов для создания надежных и эффективных приложений, управляемых данными.
Читайте также:
- Как создать сетевой API с помощью Express.js, Bun и MongoDB
- Как создать опрос удовлетворенности сотрудников с Angular и сохранить его результаты в коллекции MongoDB
- Как подключиться к MongoDB с помощью Node.js
Читайте нас в Telegram, VK и Дзен
Перевод статьи Siddiquiaffan: Mongoose Hooks: Everything You Need to Know