@IsMongoId

Проверка идентификатора MongoDB в формате ObjectId в class-validator реализуется через декоратор @IsMongoId. Он предназначен для валидации строковых значений, которые должны соответствовать стандартному представлению MongoDB ObjectId — 24-символьной шестнадцатеричной строки.


MongoDB использует специальный тип идентификатора документов — ObjectId. Его строковое представление:

  • состоит из 24 символов
  • включает только символы 0-9 и a-f
  • является hex-строкой

Примеры корректных значений:

507f1f77bcf86cd799439011
64b21f2e8f1a2c3d4e5f6789
aaaaaaaaaaaaaaaaaaaaaaaa

Любое отклонение от структуры делает строку невалидной для ObjectId.


Назначение @IsMongoId

Декоратор @IsMongoId применяется для проверки того, что значение:

  • является строкой
  • соответствует формату MongoDB ObjectId
  • не содержит лишних символов или пробелов
  • имеет строго длину 24 символа

Фактически он выполняет регулярную проверку на соответствие hex-формату ObjectId.


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

В типичных DTO-классах (например, в NestJS) декоратор используется для валидации входящих параметров.

import { IsMongoId } from 'class-validator';

export class GetUserDto {
  @IsMongoId()
  id: string;
}

При передаче запроса:

{
  "id": "64b21f2e8f1a2c3d4e5f6789"
}

значение будет считаться корректным.

Если же передать:

{
  "id": "12345"
}

валидация завершится ошибкой.


Поведение при ошибке валидации

Если строка не соответствует формату ObjectId:

  • создаётся ошибка валидации
  • поле помечается как некорректное
  • общий запрос может быть отклонён (в зависимости от настроек ValidationPipe)

Пример сообщения по умолчанию:

id must be a mongodb id

Внутренняя логика проверки

@IsMongoId опирается на проверку структуры строки:

  • длина строго 24 символа
  • допустимые символы: 0-9, a-f, A-F
  • отсутствие пробелов и разделителей

По сути, это строгая форма проверки hex-строки фиксированной длины.


Использование в параметрах контроллера

В серверных фреймворках часто применяется для проверки route-параметров.

import { Param } from '@nestjs/common';
import { IsMongoId } from 'class-validator';

export class UserParams {
  @IsMongoId()
  userId: string;
}

И в контроллере:

@Get(':userId')
getUser(@Param() params: UserParams) {
  return params.userId;
}

Интеграция с ValidationPipe (NestJS)

Для того чтобы @IsMongoId работал в HTTP-запросах, требуется включённый пайп валидации:

app.useGlobalPipes(
  new ValidationPipe({
    whitelist: true,
    transform: true,
  }),
);

При такой конфигурации:

  • входные данные автоматически преобразуются в DTO
  • все декораторы class-validator активируются
  • некорректные запросы блокируются до попадания в бизнес-логику

Поведение с пустыми значениями

Важно учитывать, что @IsMongoId:

  • не считает null валидным значением
  • не пропускает undefined
  • не игнорирует пустую строку

Примеры:

Значение Результат
null ошибка
undefined ошибка
"" ошибка
"507f1f77bcf86cd799439011" ок

Совместное использование с другими декораторами

Часто @IsMongoId комбинируется с другими проверками для усиления типизации.

import { IsMongoId, IsString } from 'class-validator';

export class UpdateDto {
  @IsMongoId()
  id: string;

  @IsString()
  name: string;
}

Также часто добавляют ограничения на обязательность поля:

import { IsMongoId, IsNotEmpty } from 'class-validator';

export class DeleteDto {
  @IsNotEmpty()
  @IsMongoId()
  id: string;
}

Порядок декораторов не влияет на итоговую валидацию, так как все проверки выполняются независимо.


Поведение с массивами

Сам по себе @IsMongoId не предназначен для массивов. Для проверки массива ObjectId используется комбинация:

import { IsMongoId, IsArray } from 'class-validator';

export class BatchDto {
  @IsArray()
  @IsMongoId({ each: true })
  ids: string[];
}

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

  • each: true заставляет валидировать каждый элемент массива отдельно

Частые ошибки при использовании

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

{
  "id": 123456
}

Ошибка возникает из-за несоответствия типу string.


UUID вместо ObjectId

{
  "id": "550e8400-e29b-41d4-a716-446655440000"
}

UUID валиден как идентификатор, но не проходит @IsMongoId.


Пробелы и скрытые символы

{
  "id": " 64b21f2e8f1a2c3d4e5f6789 "
}

Любые пробелы делают значение невалидным.


Валидация в сочетании с трансформацией типов

При использовании class-transformer важно учитывать, что @IsMongoId работает только с уже приведённым к строке значением.

import { Type } from 'class-transformer';
import { IsMongoId } from 'class-validator';

export class ExampleDto {
  @Type(() => String)
  @IsMongoId()
  id: string;
}

Это снижает риск ошибок при получении данных из JSON или query-параметров.


Роль в архитектуре API

Использование @IsMongoId позволяет:

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

При работе с MongoDB это один из базовых валидаторов, обеспечивающих целостность идентификаторов на уровне входного слоя приложения.