Концепция middleware

В библиотеке Navigo middleware представляет собой промежуточный слой обработки маршрутов, позволяющий выполнять действия до или после перехода на определённый маршрут. Middleware играет ключевую роль в построении сложных клиентских приложений, обеспечивая управление аутентификацией, логированием, асинхронной загрузкой данных и другими аспектами маршрутизации.


Принцип работы middleware

Middleware — это функции, которые принимают объект контекста маршрута и функцию next. Контекст содержит всю информацию о текущем маршруте, включая параметры, путь и состояние навигации. Вызов next() передаёт управление следующему middleware или основному обработчику маршрута.

router.on('/dashboard', (params, query) => {
    console.log('Главная страница dashboard');
}).middleware((context, next) => {
    console.log('Проверка авторизации');
    if (context.user.isAuthenticated) {
        next();
    } else {
        router.navigate('/login');
    }
});

В этом примере middleware проверяет авторизацию пользователя. Если пользователь аутентифицирован, вызов next() передаёт управление основному обработчику. Если нет — происходит перенаправление на страницу входа.


Создание глобальных и локальных middleware

Глобальные middleware применяются ко всем маршрутам и регистрируются с помощью метода use:

router.use((context, next) => {
    console.log('Глобальная проверка');
    next();
});

Локальные middleware назначаются конкретным маршрутам через метод on или цепочку вызовов:

router.on('/profile', (params, query) => {
    console.log('Профиль пользователя');
}).middleware((context, next) => {
    console.log('Проверка прав доступа к профилю');
    next();
});

Глобальные middleware всегда выполняются до локальных, что позволяет строить иерархическую структуру обработки маршрутов.


Асинхронные операции в middleware

Middleware в Navigo поддерживает асинхронность через async/await или промисы. Это особенно полезно для загрузки данных с сервера перед отображением страницы.

router.on('/reports', async (params, query) => {
    console.log('Отображение отчетов');
}).middleware(async (context, next) => {
    context.reports = await fetchReportsFromServer();
    next();
});

Контекст маршрута может быть расширен дополнительными свойствами, доступными на всех последующих этапах обработки маршрута.


Цепочка middleware

В Navigo middleware могут выстраиваться в цепочку, выполняясь последовательно. Каждый middleware должен вызывать next() для передачи управления следующему в цепочке. Пропуск next() прерывает выполнение маршрута.

router.use(authMiddleware)
      .use(loggingMiddleware)
      .on('/settings', settingsHandler);

В этой цепочке authMiddleware проверяет авторизацию, затем loggingMiddleware записывает информацию о маршруте, после чего вызывается обработчик settingsHandler.


Контекст маршрута (Route Context)

Контекст маршрута содержит ключевые свойства:

  • pathname — путь маршрута, включая параметры.
  • params — объект с параметрами маршрута.
  • query — объект с GET-параметрами.
  • userDefinedData — пространство для хранения пользовательских данных.
  • user — информация о текущем пользователе, если реализована авторизация.

Middleware имеет полный доступ к контексту, что позволяет изменять данные до передачи их основному обработчику.


Использование middleware для управления доступом

Middleware широко применяется для реализации ролей и уровней доступа:

function roleMiddleware(requiredRole) {
    return (context, next) => {
        if (context.user.role === requiredRole) {
            next();
        } else {
            router.navigate('/unauthorized');
        }
    };
}

router.on('/admin', adminHandler)
      .middleware(roleMiddleware('admin'));

Такая схема обеспечивает гибкое управление доступом без дублирования логики в каждом маршруте.


Логирование и аналитика через middleware

Middleware удобно использовать для отслеживания пользовательской активности и аналитики:

router.use((context, next) => {
    console.log(`Переход на маршрут: ${context.pathname}`);
    sendAnalytics(context.pathname);
    next();
});

Любой переход через Navigo автоматически проходит через глобальные middleware, что позволяет централизованно собирать статистику.


Комбинация middleware и lazy loading

Middleware может быть использован для динамической подгрузки компонентов или модулей, обеспечивая ленивую загрузку страниц:

router.on('/dashboard', async (params, query) => {
    const { Dashboard } = await import('./Dashboard.js');
    new Dashboard().render();
}).middleware(async (context, next) => {
    await loadUserData(context.user.id);
    next();
});

Это позволяет оптимизировать производительность, загружая тяжелые компоненты только при необходимости.


Middleware в Navigo создаёт мощный и гибкий инструмент для управления потоками маршрутизации, позволяя реализовать авторизацию, асинхронную обработку данных, логирование и другие задачи без дублирования кода. Эффективное использование middleware значительно повышает масштабируемость и поддерживаемость клиентских приложений на JavaScript.