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

Page.js предоставляет возможность создавать клиентские маршруты с динамическими параметрами, которые извлекаются прямо из URL. Параметры определяются в пути маршрута через двоеточие (:). Например, маршрут /user/:id позволяет получить значение id из URL.

page('/user/:id', ctx => {
  console.log(ctx.params.id);
});

В объекте ctx.params хранятся все значения параметров маршрута. Если путь /user/42, то ctx.params.id будет равен "42".


Ограничение и проверка параметров

Иногда необходимо, чтобы параметры соответствовали определённому формату: числовому, строковому или регулярному выражению. Page.js позволяет использовать регулярные выражения прямо в пути маршрута:

page('/order/:orderId(\\d+)', ctx => {
  console.log(ctx.params.orderId);
});

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


Пользовательская валидация через middleware

Для более сложной логики валидации параметров используется middleware. Middleware функции принимают объект ctx и next, что позволяет проверять параметры до основной обработки маршрута.

function validateUserId(ctx, next) {
  const id = ctx.params.id;
  if (!/^\d+$/.test(id)) {
    page.redirect('/error');
    return;
  }
  next();
}

page('/user/:id', validateUserId, ctx => {
  console.log(`User ID: ${ctx.params.id}`);
});

В этом примере сначала выполняется проверка регулярным выражением, и только если проверка пройдена, вызывается основной обработчик маршрута. В случае ошибки пользователь перенаправляется на страницу /error.


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

Page.js позволяет использовать несколько параметров в одном маршруте. Для каждого из них можно определить отдельную проверку или объединить в одну функцию middleware:

function validateParams(ctx, next) {
  const { userId, postId } = ctx.params;
  if (!/^\d+$/.test(userId) || !/^\d+$/.test(postId)) {
    page.redirect('/error');
    return;
  }
  next();
}

page('/user/:userId/post/:postId', validateParams, ctx => {
  console.log(`User: ${ctx.params.userId}, Post: ${ctx.params.postId}`);
});

Такой подход обеспечивает централизованную валидацию и повышает читаемость кода при работе с несколькими динамическими сегментами URL.


Преобразование параметров

После валидации часто требуется привести параметры к нужному типу. Page.js хранит все параметры как строки, поэтому преобразование в числа или булевы значения необходимо выполнять вручную:

page('/product/:productId', ctx => {
  const productId = parseInt(ctx.params.productId, 10);
  if (isNaN(productId)) {
    page.redirect('/error');
    return;
  }
  console.log(`Product ID: ${productId}`);
});

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


Асинхронная валидация

Иногда параметры требуют проверки на сервере, например, проверка существования пользователя. Page.js поддерживает асинхронные middleware через async функции:

async function checkUserExists(ctx, next) {
  const response = await fetch(`/api/users/${ctx.params.id}`);
  if (!response.ok) {
    page.redirect('/not-found');
    return;
  }
  next();
}

page('/user/:id', checkUserExists, ctx => {
  console.log(`User exists: ${ctx.params.id}`);
});

Асинхронная проверка позволяет интегрировать маршруты Page.js с API и базами данных без блокировки интерфейса.


Валидация с использованием query-параметров

Кроме динамических сегментов пути, Page.js предоставляет объект ctx.querystring, содержащий строку запроса. Для удобства её можно парсить в объект:

function parseQuery(ctx, next) {
  const params = Object.fromEntries(new URLSearchParams(ctx.querystring));
  ctx.query = params;
  next();
}

page('/search', parseQuery, ctx => {
  console.log(ctx.query.q); // значение параметра q
});

Валидация query-параметров позволяет фильтровать или корректировать данные до их использования в приложении.


Резюме ключевых техник валидации

  • Регулярные выражения в пути для простой проверки формата.
  • Middleware для сложной и централизованной логики.
  • Преобразование типов после извлечения параметров.
  • Асинхронная валидация при необходимости обращения к API.
  • Обработка query-параметров для дополнительной фильтрации данных.

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