Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI3 апр. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Параметр next в middleware
Это ключевой концепт для понимания как работает middleware паттерн. Разберём со всех сторон.
Что такое middleware?
Middleware — это функция, которая обрабатывает HTTP запрос, выполняет какие-то действия, и затем передаёт управление следующему middleware или обработчику.
// Базовая структура middleware
function middleware(req, res, next) {
// 1. Выполняем какое-то действие
console.log('Запрос получен');
// 2. Вызываем next() для передачи управления дальше
next();
// 3. Код может выполниться ПОСЛЕ next()
console.log('Запрос завершён');
}
Понимание параметра next
Параметр next — это функция, которая вызывает следующий middleware в цепочке:
// Цепочка middleware в Express
app.use(middleware1); // middleware 1
app.use(middleware2); // middleware 2
app.use(middleware3); // middleware 3
app.get('/users', handler); // конечный обработчик
// Когда приходит запрос, выполняется:
// middleware1(req, res, next1) {
// next1(); // -> middleware2
// }
// middleware2(req, res, next2) {
// next2(); // -> middleware3
// }
// middleware3(req, res, next3) {
// next3(); // -> handler
// }
// handler(req, res) {
// res.json(data);
// }
Практические примеры
Пример 1: Логирование
const express = require('express');
const app = express();
// Middleware для логирования
function loggerMiddleware(req, res, next) {
console.log(`[${new Date().toISOString()}] ${req.method} ${req.url}`);
next(); // передаём управление дальше
}
app.use(loggerMiddleware);
app.get('/users', (req, res) => {
res.json({ users: [] });
});
// Вывод:
// [2024-01-15T10:30:00.000Z] GET /users
Пример 2: Аутентификация
function authMiddleware(req, res, next) {
const token = req.headers.authorization;
if (!token) {
// Не вызываем next() - прерываем цепочку
return res.status(401).json({ error: 'Unauthorized' });
}
try {
const decoded = verifyToken(token);
req.user = decoded; // добавляем данные пользователя
next(); // вызываем next если аутентификация успешна
} catch (error) {
res.status(401).json({ error: 'Invalid token' });
}
}
app.use(authMiddleware); // применяем ко всем маршрутам
app.get('/protected', (req, res) => {
res.json({ user: req.user }); // req.user добавлен middleware
});
Пример 3: Обработка ошибок
function errorHandler(err, req, res, next) {
// Обработчик ошибок ВСЕГДА имеет 4 параметра!
console.error('Ошибка:', err);
res.status(err.status || 500).json({
error: err.message
});
}
app.get('/data', (req, res, next) => {
try {
const data = fetchData();
res.json(data);
} catch (error) {
next(error); // передаём ошибку в обработчик ошибок
}
});
app.use(errorHandler); // ДОЛЖЕН быть последним!
Порядок выполнения middleware
Это очень важно понимать:
const express = require('express');
const app = express();
// 1. Парсинг JSON
app.use(express.json());
// 2. Логирование
app.use((req, res, next) => {
console.log('1. Логирование');
next();
});
// 3. Проверка аутентификации
app.use((req, res, next) => {
console.log('2. Аутентификация');
next();
});
// 4. Специальный маршрут
app.get('/users', (req, res, next) => {
console.log('3. Обработчик /users');
res.json({ users: [] });
});
// 5. Другой маршрут
app.get('/posts', (req, res) => {
console.log('4. Обработчик /posts');
res.json({ posts: [] });
});
// Вывод для GET /users:
// 1. Логирование
// 2. Аутентификация
// 3. Обработчик /users
// Вывод для GET /posts:
// 1. Логирование
// 2. Аутентификация
// 4. Обработчик /posts
Что происходит если НЕ вызвать next()?
Если забыть вызвать next(), управление не передаётся дальше:
app.use((req, res, next) => {
console.log('Middleware 1');
// ЗАБЫЛИ вызвать next()!
});
app.get('/test', (req, res) => {
console.log('Handler'); // НИКОГДА НЕ ВЫПОЛНИТСЯ!
res.json({ ok: true });
});
// Запрос повисает, так как никто не отправляет ответ!
Асинхронные middleware
В современном Node.js используются async функции:
const express = require('express');
const app = express();
// Async middleware
app.use(async (req, res, next) => {
try {
const user = await fetchUserFromDB(req.userId);
req.currentUser = user;
next(); // передаём управление дальше
} catch (error) {
next(error); // передаём ошибку в обработчик
}
});
app.get('/profile', async (req, res, next) => {
try {
const profile = await getProfile(req.currentUser.id);
res.json(profile);
} catch (error) {
next(error); // ошибка перехватится errorHandler
}
});
Правила использования next
// ПРАВИЛО 1: Вызывай next() или отправь ответ
function middleware(req, res, next) {
if (shouldContinue) {
next(); // передаём дальше
} else {
res.status(400).json({ error: 'Bad request' }); // отправляем ответ
}
}
// ПРАВИЛО 2: Не вызывай next() дважды
function badMiddleware(req, res, next) {
next();
next(); // БЕД! Может привести к проблемам
}
// ПРАВИЛО 3: Отправляй ответ или вызывай next(), но не оба
function middleware(req, res, next) {
// ПЛОХО:
res.json({ ok: true });
next(); // Это странно и может вызвать проблемы
// ХОРОШО:
if (someCondition) {
res.json({ ok: true });
} else {
next();
}
}
// ПРАВИЛО 4: Передавай ошибки в next(error)
function middleware(req, res, next) {
try {
const data = JSON.parse(req.body);
next();
} catch (error) {
next(error); // передаём ошибку, не просто вызываем
}
}
Визуализация цепочки
Запрос приходит
|
v
[middleware 1] --> next() вызвана?
| |
| ДА -> [middleware 2] --> next() вызвана?
| | |
| | ДА -> [middleware 3] --> next() вызвана?
| | | |
| | | ДА -> [handler]
| | | |
| | | v
| | | [отправляем ответ]
| | | ^
| | | НЕТ / ошибка |
| | | |
| | +-------> [errorHandler]
| | ^
| | НЕТ / ошибка |
| +-------> [errorHandler]
| ^
| НЕТ / ошибка |
+-------> [errorHandler]
Практический пример: полная цепочка
const express = require('express');
const app = express();
// 1. Парсинг JSON
app.use(express.json());
// 2. Логирование
app.use((req, res, next) => {
console.log(`Запрос: ${req.method} ${req.url}`);
next();
});
// 3. Проверка токена
app.use((req, res, next) => {
const token = req.headers.authorization;
if (!token && req.url !== '/login') {
return res.status(401).json({ error: 'No token' });
}
next();
});
// 4. Добавление user в request
app.use((req, res, next) => {
req.user = { id: 1, name: 'John' }; // пример
next();
});
// 5. Обработчик маршрута
app.get('/users', (req, res) => {
res.json({ users: [], currentUser: req.user });
});
// 6. Обработчик ошибок
app.use((err, req, res, next) => {
console.error('Ошибка:', err);
res.status(500).json({ error: err.message });
});
app.listen(3000);
// Когда приходит GET /users:
// Логирование -> Проверка токена -> Добавление user -> Обработчик
Заключение
Параметр next — это функция, которая передаёт управление следующему middleware. Она критична для управления потоком выполнения в Express приложении. Понимание этого паттерна очень важно для разработки backend приложений.