NestJS. Не работает глобальная валидация данных, если dto указан как union type, какая есть альтернатива?

Рейтинг: 0Ответов: 1Опубликовано: 24.03.2023

Есть обработчик запроса в контроллере, который отвечает за создание пользователей. Пользователи бывают двух видов с ролью Тренер и с ролью Клиент. В зависимости от роли пользователя могу приходить 2 вида данных. Соответственно я создал 2 dto класса - CreateClientDto, CreateTrainerDto. В обработчике я указал для dto типизацию, как объединение двух этих классов - CreateClientDto | CreateTrainerDto:

@Post('register')
  public async create(@Body() dto: CreateClientDto | CreateTrainerDto) {
    const newUser = await this.authService.register(dto);

    if (newUser.role === UserRole.Client) {
      return fillDTO(ClientRdo, newUser);
    }

    return fillDTO(TrainerRdo, newUser);
}

Но при таком раскладе валидация данных перестаёт работать. Если избавиться от union типа и указывать отдельно, или CreateClientDto, или CreateTrainerDto, то тогда всё ОК. Но такой вариант мне не подходит. Я думал о том чтобы объединить эти 2 класса в 1 универсальный класс CreateUserDto, но в этом случае у пользователя появляется возможность вне зависимости от выбранной роли комбинировать и записывать в БД свойства не характерные для своей роли.

Как можно решить данную проблему? Может можно как-то описать класс CreateUserDto, но так чтобы если у него роль Клиент, то он не мог себе присвоить свойства присущие Тренеру? И тоже самое для пользователя с ролью Тренер.

Ответы

▲ 1

Это решается либо с помощью интерфейсов, либо с помощью использования библиотеки CASL.

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

Документация

Статья на хабре