Встроенные форматы

Валидация строковых значений в JSON Schema часто требует не только проверки типа данных, но и строгого соответствия определённым шаблонам: email-адресам, URL, датам, IP-адресам и другим стандартизированным представлениям. В Ajv такие проверки реализуются через механизм форматов (formats), которые задаются свойством format в JSON Schema.

Механизм работы форматов

Формат в Ajv — это дополнительное ограничение для значений строкового типа. Он проверяется после основной валидации типа string и позволяет накладывать семантические ограничения.

Пример использования:

const schema = {
  type: "object",
  properties: {
    email: { type: "string", format: "email" }
  }
};

В данном случае строка должна не только быть строкой, но и соответствовать формату email-адреса.

Ajv не всегда включает поддержку всех форматов по умолчанию. В современных версиях библиотеки часть форматов подключается через дополнительный пакет ajv-formats.

import Ajv from "ajv";
import addFormats from "ajv-formats";

const ajv = new Ajv();
addFormats(ajv);

После подключения становятся доступны стандартные форматы, определённые спецификацией JSON Schema Draft 7 и выше.


Основные встроенные форматы

email

Формат email проверяет соответствие строки RFC-совместимому email-адресу.

Пример схемы:

{
  type: "string",
  format: "email"
}

Допустимые значения:

  • user@example.com
  • name.surname@domain.org

Недопустимые:

  • user@
  • @domain.com

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


uri

Формат uri проверяет соответствие строки универсальному идентификатору ресурса.

Пример:

{
  type: "string",
  format: "uri"
}

Допустимые значения:

  • https://example.com
  • ftp://server.local/resource
  • urn:isbn:0451450523

Ajv проверяет корректность схемы URI, включая протокол и структуру адреса.


uri-reference

Этот формат допускает как абсолютные, так и относительные URI.

Пример:

  • /users/1
  • ../assets/image.png
  • https://example.com/page

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


uuid

Формат uuid используется для проверки универсальных уникальных идентификаторов.

{
  type: "string",
  format: "uuid"
}

Поддерживаются стандартные представления UUID:

  • 550e8400-e29b-41d4-a716-446655440000

Проверка включает соответствие формату 8-4-4-4-12 и допустимым шестнадцатеричным символам.


date-time

Формат date-time соответствует RFC 3339 и ISO 8601.

Пример:

  • 2024-01-15T13:45:30Z
  • 2024-01-15T13:45:30+05:00

Ajv проверяет:

  • корректность даты
  • наличие временной зоны или суффикса Z
  • соответствие календарным ограничениям

date

Формат date используется для проверки даты без времени:

  • 2024-01-15

Важно отличие от date-time: отсутствие временной составляющей является обязательным условием.


time

Формат time проверяет строку времени:

  • 13:45:30
  • 23:59:59.999

Поддерживаются доли секунды и строгая структура HH:MM:SS.


ipv4

Формат ipv4 используется для проверки IPv4-адресов:

  • 192.168.0.1
  • 8.8.8.8

Проверка включает:

  • диапазон каждого октета (0–255)
  • правильное количество сегментов

ipv6

Формат ipv6 проверяет IPv6-адреса:

  • 2001:0db8:85a3:0000:0000:8a2e:0370:7334
  • сокращённые формы 2001:db8::1

Поддерживаются правила сокращения нулевых блоков.


hostname

Формат hostname проверяет доменные имена:

  • example.com
  • sub.domain.org

Ограничения:

  • отсутствие протоколов
  • соответствие RFC 1034/1035
  • допустимые символы ASCII и punycode

regex

Формат regex проверяет корректность регулярного выражения.

{
  type: "string",
  format: "regex"
}

Примеры:

  • ^[a-z]+$
  • \d{3}-\d{2}-\d{4}

Проверяется только синтаксис, а не соответствие строке.


Подключение и поведение форматов

В Ajv форматы могут работать в разных режимах строгости.

Строгая проверка

При включённой поддержке форматов через ajv-formats используется полноценная проверка значений.

Отключение форматов

Форматы можно отключить:

const ajv = new Ajv({ formats: false });

В этом случае format не будет влиять на результат валидации.


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

Ajv позволяет определять собственные форматы, расширяя встроенный набор.

ajv.addFormat("postal-code", {
  type: "string",
  validate: (code) => /^\d{5}$/.test(code)
});

Использование:

{
  type: "string",
  format: "postal-code"
}

Кастомные форматы полезны для:

  • бизнес-правил
  • локальных стандартов
  • специфических идентификаторов

Поведение ошибок форматов

При несоответствии формату Ajv генерирует ошибку валидации с указанием:

  • пути к полю (instancePath)
  • ожидаемого формата (keyword: "format")
  • фактического значения

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

{
  "keyword": "format",
  "message": "must match format \"email\"",
  "instancePath": "/email"
}

Оптимизация работы форматов

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

Рекомендации:

  • использовать ajv-formats только при необходимости
  • избегать сложных регулярных выражений в кастомных форматах
  • переиспользовать скомпилированные схемы
  • отключать ненужные форматы в высоконагруженных системах

Совместимость с JSON Schema Draft

Поддержка форматов зависит от версии JSON Schema:

  • Draft 7: базовые форматы
  • Draft 2019-09 и выше: расширенные возможности и строгие правила

Ajv стремится к соответствию спецификации, но реализация форматов остаётся частично расширяемой областью, где допускаются пользовательские определения и переопределения стандартных проверок.