Валидация параметров

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


Определение параметров в маршрутах

Параметры маршрутов задаются через двоеточие в пути. Например:

import UniversalRouter from 'universal-router';

const routes = [
  {
    path: '/user/:id',
    action: ({ params }) => {
      return `Пользователь с ID: ${params.id}`;
    }
  }
];

const router = new UniversalRouter(routes);

Здесь :id является параметром маршрута. Universal Router автоматически извлекает значение параметра из URL и передает его в объект params при вызове action.


Проверка типа параметров

Universal Router сам по себе не предоставляет встроенных средств строгой типизации параметров, поэтому для валидации необходимо использовать дополнительные проверки внутри action. Наиболее часто применяются проверки типов и регулярные выражения:

const routes = [
  {
    path: '/user/:id',
    action: ({ params }) => {
      const id = parseInt(params.id, 10);
      if (isNaN(id) || id <= 0) {
        throw new Error('Некорректный ID пользователя');
      }
      return `Пользователь с ID: ${id}`;
    }
  }
];

Ключевой момент: параметры маршрута из URL всегда приходят как строки. Любая логическая или числовая проверка должна выполняться явно.


Использование регулярных выражений для ограничения формата

Для ограничения формата параметров можно использовать встроенную возможность Universal Router — указание регулярного выражения прямо в пути:

const routes = [
  {
    path: '/product/:sku([A-Z0-9]{8})',
    action: ({ params }) => {
      return `Продукт с артикулом: ${params.sku}`;
    }
  }
];

В этом примере параметр sku будет соответствовать только строкам из 8 символов, содержащим заглавные буквы и цифры. Любое несоответствие приведет к тому, что маршрут не будет найден.


Валидация нескольких параметров

Маршруты могут содержать несколько параметров. Валидация каждого параметра выполняется аналогично:

const routes = [
  {
    path: '/order/:orderId/:itemId',
    action: ({ params }) => {
      const orderId = parseInt(params.orderId, 10);
      const itemId = parseInt(params.itemId, 10);

      if (isNaN(orderId) || orderId <= 0) {
        throw new Error('Некорректный ID заказа');
      }
      if (isNaN(itemId) || itemId <= 0) {
        throw new Error('Некорректный ID товара');
      }

      return `Заказ ${orderId}, товар ${itemId}`;
    }
  }
];

Регулярные выражения также могут быть применены к каждому параметру:

const routes = [
  {
    path: '/order/:orderId(\\d+)/:itemId(\\d+)',
    action: ({ params }) => `Заказ ${params.orderId}, товар ${params.itemId}`
  }
];

Валидация с использованием внешних библиотек

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

import * as Yup from 'yup';

const schema = Yup.object({
  id: Yup.number().positive().integer().required()
});

const routes = [
  {
    path: '/user/:id',
    action: async ({ params }) => {
      try {
        const validated = await schema.validate({ id: Number(params.id) });
        return `Пользователь с ID: ${validated.id}`;
      } catch (err) {
        throw new Error('Неверный параметр ID');
      }
    }
  }
];

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


Динамическая валидация на основе контекста

Universal Router позволяет использовать контекст маршрута (context) для дополнительной динамической проверки:

const routes = [
  {
    path: '/admin/:section',
    action: ({ params, context }) => {
      if (!context.user || !context.user.isAdmin) {
        throw new Error('Доступ запрещен');
      }
      return `Раздел администрирования: ${params.section}`;
    }
  }
];

const context = { user: { isAdmin: true } };

Это позволяет комбинировать проверку параметров с логикой авторизации или других бизнес-правил.


Ошибки валидации и обработка

При некорректных параметрах необходимо возвращать корректный ответ или бросать исключение. Universal Router предоставляет возможность перехватывать ошибки на уровне маршрутизатора:

router.resolve('/user/abc')
  .then(console.log)
  .catch(err => console.error('Ошибка маршрута:', err.message));

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


Рекомендации по валидации

  • Всегда явно проверять типы параметров, так как URL всегда передает строки.
  • Использовать регулярные выражения для простых ограничений формата прямо в пути.
  • Подключать библиотеки валидации для сложных и многоуровневых структур.
  • Обрабатывать ошибки централизованно, чтобы не допускать некорректное выполнение действий.
  • Комбинировать валидацию с контекстом маршрута, если параметры должны проверяться относительно состояния приложения.

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