Вопрос проверяет понимание концепции промежуточного ПО (middleware) в контексте веб-фреймворков, его назначения для обработки запросов и ответов, а также практический опыт его реализации.
Middleware — это фундаментальная концепция в веб-фреймворках, особенно в Node.js с Express. Это функции, которые выполняются в цепочке между получением HTTP-запрора и отправкой ответа. Они позволяют инкапсулировать общую логику, такую как аутентификация, валидация, логирование или сжатие данных, избегая её дублирования в каждом обработчике маршрута.
Каждая функция middleware получает три параметра: объект запроса (req), объект ответа (res) и функцию next. Ключевая идея — middleware может либо модифицировать req и res, либо завершить цикл, отправив ответ, либо передать управление дальше, вызвав next(). Если next() не вызвать, запрос "зависнет".
Допустим, нам нужно логировать метод и URL каждого входящего запроса. Мы создадим функцию и подключим её на уровне приложения, чтобы она работала для всех маршрутов.
// middleware для логирования
const requestLogger = (req, res, next) => {
const timestamp = new Date().toISOString();
console.log(`[${timestamp}] ${req.method} ${req.originalUrl}`);
// Важно: вызываем next() для передачи управления дальше
next();
};
// Подключение middleware в приложении Express
const express = require('express');
const app = express();
app.use(requestLogger); // Применяется ко всем маршрутам
app.get('/', (req, res) => {
res.send('Главная страница');
});
app.listen(3000);Middleware можно применять на разных уровнях:
app.use()): выполняется для каждого запроса.(err, req, res, next).Пример middleware для проверки API-ключа только для определённого маршрута:
const apiKeyMiddleware = (req, res, next) => {
const apiKey = req.headers['x-api-key'];
if (apiKey === 'secret-key-123') {
next(); // Ключ верный, продолжаем
} else {
res.status(401).json({ error: 'Invalid API Key' }); // Завершаем цикл
}
};
app.use('/api/admin', apiKeyMiddleware); // Защищаем только маршруты /api/admin/*Вывод: Собственные middleware стоит писать для любой сквозной функциональности, которую нужно применить к нескольким маршрутам. Это делает код чище, соблюдает принцип DRY (Don't Repeat Yourself) и позволяет легко добавлять или отключать слои обработки, такие как безопасность, мониторинг или подготовка данных.