Валидация данных

В библиотеке Lighthouse валидация данных реализуется через мощную систему схем и правил проверки, позволяющую обеспечивать целостность и корректность данных при их обработке и передаче. Основной принцип работы — создание схемы данных, которая определяет структуру, типы и ограничения для объектов и массивов.


Создание схемы данных

Схема в Lighthouse задаётся с помощью функции schema(), принимающей объект, где ключи соответствуют полям данных, а значения — правилам валидации. Каждое правило может быть простым (например, string, number) или составным (например, вложенные объекты и массивы).

Пример простой схемы:

const userSchema = schema({
  name: string().required(),
  age: number().min(0).max(120),
  email: string().email().required()
});

Ключевые моменты:

  • required() — обязательное поле.
  • min() и max() — ограничения для числовых значений.
  • email() — встроенная проверка формата электронной почты.

Схема может включать вложенные объекты:

const postSchema = schema({
  title: string().required(),
  author: schema({
    id: number().required(),
    name: string().required()
  }),
  tags: array().of(string())
});

Здесь author — это вложенный объект с собственной схемой, а tags — массив строк.


Валидация данных

Для проверки данных используется метод validate() схемы:

const data = {
  name: 'Алексей',
  age: 30,
  email: 'alex@example.com'
};

const result = userSchema.validate(data);

Возвращаемое значение представляет собой объект с двумя ключами:

  • valid — булево значение, показывающее успешность валидации.
  • errors — объект с сообщениями об ошибках для каждого поля, если они есть.

Пример обработки ошибок:

if (!result.valid) {
  console.log(result.errors);
}

Пользовательские правила валидации

Lighthouse поддерживает создание собственных валидаторов через функцию custom():

const passwordSchema = string().custom(value => {
  if (!/[A-Z]/.test(value)) return 'Пароль должен содержать заглавную букву';
  if (value.length < 8) return 'Пароль слишком короткий';
  return true;
});

Функция должна возвращать либо true при успешной проверке, либо строку с сообщением об ошибке. Пользовательские валидаторы могут быть цепочкой для одного поля:

const userPasswordSchema = schema({
  password: string()
    .required()
    .custom(value => value.includes('!') ? true : 'Пароль должен содержать спецсимвол')
});

Валидация массивов и сложных структур

Для массивов используется метод array().of(), который позволяет задать тип и схему элементов массива:

const usersSchema = array().of(
  schema({
    id: number().required(),
    username: string().required(),
    roles: array().of(string().oneOf(['admin', 'user', 'guest']))
  })
);

Особенности:

  • oneOf() проверяет, что значение принадлежит набору допустимых.
  • Можно комбинировать вложенные схемы с массивами для сложных данных.

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

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

const emailSchema = string().custom(async value => {
  const exists = await checkEmailInDatabase(value);
  if (exists) return 'Email уже зарегистрирован';
  return true;
});

Метод validate() в этом случае возвращает промис:

await emailSchema.validate({ email: 'test@example.com' });

Комплексные правила и цепочки

Lighthouse позволяет комбинировать правила для одного поля:

const profileSchema = schema({
  username: string()
    .required()
    .min(3)
    .max(20)
    .custom(value => /^[a-zA-Z0-9_]+$/.test(value) ? true : 'Допустимы только латинские буквы, цифры и подчёркивания'),
  age: number()
    .min(13)
    .max(120)
});

Такая цепочка обеспечивает:

  • Наличие значения (required)
  • Диапазон длины или значения (min, max)
  • Пользовательскую проверку формата

Интеграция с формами и API

Схемы Lighthouse легко интегрируются с фронтенд-формами и API-запросами. Валидация может происходить на клиенте перед отправкой данных, а на сервере — дублироваться для надёжности. Это позволяет:

  • Исключить некорректные данные на раннем этапе
  • Обеспечить согласованность данных на всех уровнях приложения
  • Создать централизованную систему правил для всех моделей данных

Логирование и локализация ошибок

Ошибки в Lighthouse можно локализовать и форматировать:

const result = userSchema.validate(data, { locale: 'ru' });

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


Рекомендации по структуре схем

  • Разделять схемы по функциональным областям (пользователи, посты, товары)
  • Использовать вложенные схемы для объектов внутри объектов
  • Использовать массивы с проверкой элементов для коллекций
  • При необходимости включать асинхронные проверки для уникальных данных или внешних источников

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