В библиотеке реализована модель декларативной валидации, в которой правила описываются не в виде процедурного кода, а через аннотации классов и их свойств. Эти аннотации не выполняют проверку напрямую — они формируют структуру данных, описывающую правила. Такая структура и называется метаданными в контексте системы.
Метаданные представляют собой промежуточный слой между декларацией и выполнением валидации. Каждый декоратор добавляет в общий реестр информацию о том, какие ограничения должны применяться к конкретному свойству класса.
Ключевая идея заключается в том, что:
В экосистеме TypeScript и JavaScript метаданные обычно связываются с
использованием пакета reflect-metadata. Он расширяет
возможности рефлексии и позволяет привязывать произвольные данные к
классам и их свойствам.
Базовый механизм выглядит следующим образом:
Типовой набор операций включает:
Используемые ключи не являются частью публичного API JavaScript и задаются библиотекой валидации.
Каждое правило валидации преобразуется в объект метаданных. Эти объекты формируют массив, связанный с конкретным свойством.
Типичная структура метаданных включает:
Каждый декоратор добавляет отдельный элемент в этот массив. Например, несколько декораторов на одном свойстве приводят к накоплению нескольких метаданных.
Декораторы не выполняют проверку напрямую. Их задача — зарегистрировать описание ограничения.
При использовании декоратора:
@IsString()
name: string;
происходит следующее:
isString;name;Каждый следующий декоратор дополняет этот набор, а не заменяет его.
Библиотека использует внутреннюю структуру хранения, которая организована как иерархия:
Такая структура позволяет эффективно:
Хранилище работает как глобальный реестр, индексированный по конструкторам классов.
При использовании наследования классов метаданные также наследуются. Это позволяет расширять модели данных без повторного описания всех ограничений.
Механизм наследования включает:
Это поведение особенно важно при построении сложных доменных моделей, где общие правила выносятся в базовые сущности.
Метаданные могут формироваться не только статически через декораторы, но и динамически через программный API.
Поддерживаются сценарии:
Для этого используется функция регистрации пользовательских валидаторов и декораторов, которая добавляет метаданные в общий реестр вручную.
Механизм registerDecorator позволяет создавать
собственные правила, которые становятся частью системы метаданных.
При регистрации указываются:
После регистрации создаётся такой же объект метаданных, как и у встроенных декораторов. Это обеспечивает единообразие обработки.
Функция validate не содержит жёстко зашитых правил для
каждого случая. Вместо этого она:
Таким образом, метаданные выступают в роли промежуточного языка описания ограничений, а валидатор — как интерпретатор этого языка.
Метаданные поддерживают группировку, позволяющую разделять сценарии валидации.
Группы используются для:
Каждое правило может содержать список групп, к которым оно относится. При запуске валидации можно указать активные группы, и только соответствующие метаданные будут учитываться.
Помимо групп, метаданные могут содержать условия выполнения:
Такие условия хранятся в объекте метаданных и учитываются во время интерпретации.
При наличии нескольких правил на одном свойстве порядок их применения определяется порядком регистрации.
Особенности обработки:
Некоторые типы ограничений могут прерывать дальнейшую проверку свойства, если это предусмотрено опциями.
Метаданные используются не только для проверки, но и для
преобразования данных при использовании совместно с
class-transformer.
В этом случае:
Такая связка позволяет строить полноценные пайплайны обработки входных данных.
Для повышения производительности система кэширует результаты извлечения метаданных.
Кэш включает:
Это позволяет избегать повторного анализа декораторов при каждой валидации одного и того же класса.
Метаданные могут быть извлечены напрямую для анализа структуры валидации.
При инспекции доступны:
Это используется как внутри библиотеки, так и во внешних инструментах генерации схем и документации.
Модель метаданных позволяет расширять систему без изменения ядра:
Метаданные выступают стабильным контрактом между декларацией и выполнением, что делает архитектуру гибкой и расширяемой.