@IsJSON

Декоратор @IsJSON используется для проверки того, что строковое значение является корректной JSON-строкой. Валидация основана на попытке парсинга значения через JSON.parse, с дополнительной проверкой структуры и синтаксиса JSON согласно спецификации ECMAScript.

Ключевая особенность проверки заключается в том, что валидируется именно строка, а не уже распарсенный объект. Это важно при работе с DTO, где данные приходят из HTTP-запросов в текстовом виде.


Принцип работы @IsJSON

Внутренняя логика проверки сводится к следующим шагам:

  • значение должно быть строкой;
  • строка должна быть непустой;
  • выполняется попытка JSON.parse(value);
  • при возникновении ошибки парсинга значение считается невалидным;
  • результатом валидного JSON может быть объект, массив, число, строка, true, false или null.

Таким образом, валидатор не ограничивает структуру JSON, а проверяет исключительно синтаксическую корректность.


Базовое использование

import { IsJSON } from 'class-validator';

export class CreateConfigDto {
  @IsJSON()
  config: string;
}

В данном случае поле config должно содержать строку, которая успешно парсится как JSON.

Примеры валидных значений:

{"a":1}
[1, 2, 3]
"string"
null

Поведение при различных входных данных

Корректные случаи

Строка с объектом:

'{"name":"Alex","age":25}'

Строка с массивом:

'[{"id":1},{"id":2}]'

Примитивы:

'123'
'"text"'
'true'

Некорректные случаи

Пустая строка:

''

Невалидный JSON:

'{name:Alex}'
'{ "a": 1,, }'
undefined
'Hello world'

Отличие от проверки объектов

@IsJSON не предназначен для проверки JavaScript-объектов. Следующий пример не пройдет валидацию:

const obj = { a: 1 };

Если значение уже является объектом, используется другой набор декораторов:

  • @IsObject
  • @ValidateNested
  • @Type(() => Class)

@IsJSON строго ориентирован на строковое представление данных.


Взаимодействие с JSON.parse

Фактическая проверка эквивалентна:

function isJSON(value: string): boolean {
  try {
    JSON.parse(value);
    return true;
  } catch {
    return false;
  }
}

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


Типичные ошибки использования

Передача объекта вместо строки

config: { a: 1 }

Ошибка возникает потому, что JSON.parse применяется только к строкам.


Двойное кодирование JSON

'"{\"a\":1}"'

Такой случай валиден с точки зрения JSON, но часто является результатом неправильной сериализации на стороне клиента.


Потеря структуры после трансформации

При использовании class-transformer возможно автоматическое преобразование типов, из-за чего строка может стать объектом до момента валидации, что делает @IsJSON неприменимым.


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

В типичной схеме обработки запроса:

@Post()
create(@Body() dto: CreateConfigDto) {
  return dto;
}

валидация происходит до попадания данных в метод контроллера. @IsJSON отрабатывает на этапе проверки DTO.

Важно учитывать порядок:

  • сначала transform (если включён ValidationPipe);
  • затем валидация;
  • затем доступ к данным в контроллере.

Валидация вложенного JSON

@IsJSON не проверяет структуру содержимого JSON. Например:

config: '{"user":{"name":123}}'

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

Для структурной проверки требуется:

  • парсинг JSON вручную;
  • последующая валидация через DTO;
  • либо кастомные валидаторы.

Работа с массивами и вложенными структурами

JSON следующего вида валиден:

'[{"id":1},{"id":2}]'
'{"items":[1,2,3],"meta":{"count":3}}'

@IsJSON не ограничивает глубину вложенности и размер структуры.


Обработка null и примитивов

Допустимые JSON-примитивы:

  • null
  • числа (123, 3.14)
  • строки ("text")
  • булевы значения (true, false)

Пример:

'null'
'42'
'"abc"'
'false'

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

Поскольку основой является JSON.parse, стоимость операции зависит от:

  • размера строки;
  • глубины структуры;
  • количества вложенных объектов и массивов.

На больших JSON-строках возможны заметные затраты CPU, особенно при массовой валидации входящих запросов.


Особенности обработки пробелов и форматирования

Следующие строки считаются валидными:

'{ "a" : 1 }'
'
{
  "a": 1
}
'

JSON допускает пробелы и переносы строк вне строковых значений, что учитывается валидатором.


Поведение при undefined и отсутствующих значениях

Если поле отсутствует:

{}

валидация @IsJSON не выполняется, если не добавлены дополнительные декораторы:

  • @IsDefined
  • @IsOptional

Значение undefined не является валидным JSON и приводит к ошибке при прямой проверке.


Комбинация с другими валидаторами

Часто используется совместно:

@IsString()
@IsJSON()
config: string;

или с ограничением обязательности:

@IsNotEmpty()
@IsJSON()
config: string;

Порядок декораторов не влияет на результат, но влияет на читаемость и диагностику ошибок.


Ограничения применения

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

Основная роль — синтаксическая проверка строкового JSON.