Документирование валидационных правил

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

Документирование валидации — это не описание «что делает код», а фиксация смысловых ограничений данных: какие значения допустимы, почему они допустимы и как эти ограничения связаны с предметной областью.


Структурирование схем как основа документации

В Yup схема является декларативным описанием объекта. Уже сама структура схемы может выступать документацией, если она написана последовательно и логично.

Пример базовой схемы:

import * as Yup from 'yup';

const userSchema = Yup.object({
  email: Yup.string()
    .email('Некорректный формат email')
    .required('Email обязателен'),

  age: Yup.number()
    .min(18, 'Возраст должен быть не менее 18')
    .max(120, 'Некорректное значение возраста')
});

Даже в таком виде схема уже несёт часть документации, но она остаётся частично скрытой: не объясняет бизнес-логику ограничений.


Использование .label() для семантического описания полей

Метод .label() позволяет добавить человекочитаемое имя поля, которое используется в ошибках и может служить элементом документации.

const schema = Yup.object({
  firstName: Yup.string()
    .label('Имя')
    .required(),

  lastName: Yup.string()
    .label('Фамилия')
    .required()
});

Ключевой эффект:

  • ошибки становятся семантически понятнее;
  • код начинает отражать доменную модель, а не техническую структуру;
  • схема становится ближе к документации предметной области.

Комментарии как часть документирования схем

Хотя JavaScript не предоставляет специализированных средств аннотирования схем Yup, комментарии остаются важным инструментом.

const orderSchema = Yup.object({
  // Общая сумма заказа в валюте пользователя
  totalAmount: Yup.number()
    .required()
    .min(0),

  // Статус заказа определяется системой, вручную не задаётся
  status: Yup.string()
    .oneOf(['pending', 'paid', 'shipped'])
});

Комментарии должны описывать:

  • происхождение данных;
  • ограничения, неочевидные из кода;
  • связи с бизнес-процессами.

Описание схем через .describe()

Метод .describe() предоставляет машинно-читабельное описание схемы. Он полезен для генерации документации или анализа схем.

const schema = Yup.object({
  email: Yup.string().email().required(),
  age: Yup.number().min(18)
});

const description = schema.describe();

Результат содержит структуру полей, типы и ограничения. Это позволяет:

  • строить автоматическую документацию API;
  • визуализировать форму;
  • валидировать соответствие схем.

Документирование через TypeScript и типы

При использовании TypeScript Yup-схемы могут быть дополнены типами, которые выступают формой документации.

import * as Yup from 'yup';

type User = {
  email: string;
  age: number;
};

const userSchema: Yup.ObjectSchema<User> = Yup.object({
  email: Yup.string().email().required(),
  age: Yup.number().required().min(18)
});

Типы дают:

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

Централизация сообщений об ошибках

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

const messages = {
  required: 'Поле обязательно для заполнения',
  invalidEmail: 'Некорректный email адрес',
  minAge: 'Возраст ниже допустимого значения'
};

const schema = Yup.object({
  email: Yup.string()
    .email(messages.invalidEmail)
    .required(messages.required),

  age: Yup.number()
    .min(18, messages.minAge)
});

Такой подход позволяет:

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

Документирование через композицию схем

Yup поддерживает композицию схем, что можно использовать для структурирования документации.

const addressSchema = Yup.object({
  city: Yup.string().required(),
  street: Yup.string().required()
});

const userSchema = Yup.object({
  name: Yup.string().required(),
  address: addressSchema
});

Преимущества:

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

Использование .test() с поясняющими сообщениями

Кастомные валидаторы часто являются наименее документированными частями схем. Поэтому важно описывать их максимально явно.

const passwordSchema = Yup.string().test(
  'strong-password',
  'Пароль должен содержать минимум 8 символов, цифру и букву',
  (value) => {
    return /^(?=.*[A-Za-z])(?=.*\d)[A-Za-z\d]{8,}$/.test(value || '');
  }
);

В таких случаях:

  • название теста фиксирует смысл проверки;
  • сообщение объясняет правило на уровне пользователя;
  • функция содержит реализацию без бизнес-объяснений.

Генерация документации из схем

Схемы Yup могут использоваться как источник для автоматической документации.

Возможные подходы:

  • преобразование schema.describe() в JSON-спецификацию;
  • генерация Markdown-документов;
  • визуализация форм в UI-библиотеках;
  • интеграция с Swagger-подобными системами.

Пример идеи структуры:

const docs = schema.describe();

Далее описание может быть преобразовано в:

  • таблицы полей;
  • списки ограничений;
  • описание вложенных объектов.

Антипаттерны документирования

Слабая документированность валидации проявляется в нескольких формах:

  • отсутствие сообщений об ошибках;
  • использование «магических» чисел без пояснений;
  • дублирование схем без структуры;
  • отсутствие семантических названий;
  • чрезмерно сложные .test() без объяснений.

Пример проблемного кода:

Yup.number().min(1000).max(999999)

Без контекста невозможно понять:

  • что означает диапазон;
  • почему именно такие границы;
  • к какой бизнес-логике это относится.

Связь документации и поддержки схем

Документирование валидационных правил напрямую влияет на сопровождение системы:

  • упрощается изменение бизнес-логики;
  • снижается риск регрессий;
  • ускоряется онбординг разработчиков;
  • повышается предсказуемость поведения форм.

Yup в этом контексте выступает не только как инструмент валидации, но и как формализованное описание данных, которое требует дисциплины в оформлении.