Кастомные парсеры

Navigo — это легковесный роутер для JavaScript, который позволяет управлять навигацией в одностраничных приложениях. Одной из ключевых возможностей библиотеки является использование кастомных парсеров для обработки параметров маршрутов. Парсеры позволяют контролировать, как значения параметров преобразуются и интерпретируются перед передачей в обработчик маршрута.


Назначение кастомных парсеров

В стандартной конфигурации Navigo автоматически распознаёт параметры маршрутов и передаёт их в виде строк. Например:

const router = new Navigo('/');

router.on('/user/:id', ({ data }) => {
  console.log(data.id); // всегда строка
});

router.navigate('/user/42');

В этом примере data.id будет строкой '42'. Если требуется преобразовать её в число, дату или выполнить любую другую обработку, стандартного поведения недостаточно. Для этого используются кастомные парсеры.


Определение кастомного парсера

Кастомный парсер создаётся как объект с методами parse и serialize:

  • parse(value: string) → any — функция, которая принимает значение параметра из URL и возвращает преобразованное значение.
  • serialize(value: any) → string — функция, которая преобразует значение обратно в строку для формирования URL.

Пример создания числового парсера:

const numberParser = {
  parse: (value) => parseInt(value, 10),
  serialize: (value) => value.toString(),
};

Привязка кастомного парсера к маршруту

Парсер можно привязать к конкретному параметру маршрута через объект hooks при создании маршрута:

router.on('/product/:id', ({ data }) => {
  console.log(typeof data.id); // number
}, {
  hooks: {
    before: (done, params) => {
      // здесь доступ к data до вызова основного обработчика
      done();
    }
  },
  parser: {
    id: numberParser
  }
});

В этом примере data.id уже будет числом благодаря кастомному парсеру.


Глобальные парсеры

Для однотипных параметров удобно использовать глобальные парсеры, которые применяются ко всем маршрутам. Это настраивается через метод setParser экземпляра Navigo:

router.setParser({
  date: {
    parse: (value) => new Date(value),
    serialize: (value) => value.toISOString(),
  },
  int: {
    parse: (value) => parseInt(value, 10),
    serialize: (value) => value.toString(),
  }
});

router.on('/events/:date', ({ data }) => {
  console.log(data.date instanceof Date); // true
});

router.navigate('/events/2026-03-28T00:00:00.000Z');

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


Комплексные кастомные парсеры

Парсеры могут быть не только простыми преобразованиями, но и сложными функциями валидации. Например, можно создать парсер, который проверяет, соответствует ли параметр UUID формату:

const uuidParser = {
  parse: (value) => {
    const regex = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
    if (!regex.test(value)) throw new Error('Invalid UUID');
    return value;
  },
  serialize: (value) => value
};

router.on('/items/:uuid', ({ data }) => {
  console.log('UUID валиден:', data.uuid);
}, {
  parser: { uuid: uuidParser }
});

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


Использование парсеров с опциональными и регулярными параметрами

Navigo поддерживает опциональные параметры (:param?) и параметры с регулярными выражениями (:param(\\d+)). Кастомные парсеры интегрируются с этими функциями:

const router = new Navigo('/');

router.on('/search/:query?', ({ data }) => {
  console.log(data.query); // строка или undefined
}, {
  parser: {
    query: {
      parse: (value) => value ? value.trim().toLowerCase() : undefined,
      serialize: (value) => value || ''
    }
  }
});

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


Советы по проектированию парсеров

  1. Обеспечивать обратную совместимость — функция serialize должна корректно превращать данные обратно в строку URL.
  2. Обрабатывать ошибки — лучше возвращать null или undefined, если значение некорректно, чтобы не ломать работу роутера.
  3. Использовать глобальные парсеры для часто встречающихся типов данных: числа, даты, булевы значения.
  4. Не перегружать логикой — парсер отвечает только за преобразование, сложную бизнес-логику лучше вынести в обработчик маршрута.

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