【问题标题】:nestjs isn't injecting the typeorm connection in a custom validatornestjs 没有在自定义验证器中注入 typeorm 连接
【发布时间】:2021-10-01 03:38:37
【问题描述】:

我正在制定一个自定义验证器,用于验证数据库中是否存在值

我通过使用 typeorm 包中的 getConnection() 设法使代码正常工作。但理想情况下,我希望注入 typeorm 连接对象 constructor(private connection: Connection) {},这给了我更多的测试灵活性。

import { BadRequestException, Injectable } from '@nestjs/common';
import {
  ValidationArguments,
  ValidatorConstraint,
  ValidatorConstraintInterface,
} from 'class-validator';

import { Connection, getConnection } from 'typeorm';

@ValidatorConstraint({ name: 'ExistsRule', async: true })
@Injectable()
export class ExistsRule implements ValidatorConstraintInterface {
  constructor(private connection: Connection) {}

  async validate(value: number | string, args: ValidationArguments) {
    const { constraints } = args;
    if (constraints.length === 0) {
      throw new BadRequestException(`Failed validating ${value} exists.`);
    }

    const str = constraints[0].split(':');
    const tableName = str[0];
    const columnName = str[1];

    const result = await getConnection().query(
      `select count(*) from ${tableName} where ${columnName}=$1`,
      [value],
    );

    // The record already exists. Failing the validation.
    if (result[0].count > 0) {
      return false;
    }

    return true;
  }

  defaultMessage(args: ValidationArguments) {
    const { property, value } = args;

    return `${property} ${value} is already taken.`;
  }
}

正在使用此验证器的 DTO。 (为了完整性)

import {
  IsEmail,
  IsNotEmpty,
  IsPhoneNumber,
  IsString,
  Validate,
} from 'class-validator';
import { ExistsRule } from 'src/customer/exists.validator';

export class CreateCustomerDto {
  @IsString()
  firstName: string;

  @IsString()
  lastName: string;

  @IsEmail()
  @Validate(ExistsRule, ['customer:email'])
  email: string;

  @IsPhoneNumber()
  mobileNumber: string;

  @IsNotEmpty()
  password: string;
}

@Module({
  imports: [
    TypeOrmModule.forFeature([Customer]),
    JwtModule.register({
      secret: 'secret-to-be-put-in-the-env',
      signOptions: { expiresIn: '300s' },
    }),
    CommonModule,
  ],
  controllers: [BookingsController, AuthController],
  providers: [CustomerService, AuthService, LocalStrategy, JwtStrategy],
})
export class CustomerModule {}
import { Module } from '@nestjs/common';
import { UniqueRule } from './unique.validator';

@Module({
  providers: [UniqueRule],
})
export class CommonModule {}

【问题讨论】:

  • 您有任何错误吗?自定义验证器类是否添加到模块的providers 数组中?
  • 不,没有得到任何错误@JayMcDoniel 从 typeorm 包切换到 getConnection 帮助我现在让它工作。但感觉好像与将类绑定到 IOC 容器时有关。
  • 验证器是否在同一个模块的providers数组中使用验证?您是否已将 class-validator 容器设置为与 Nest 一起使用?
  • 我在一个单独的模块(通用)中有验证器,它位于通用模块的提供程序数组中。在我使用此验证器的客户模块中,我已将其添加为导入

标签: nestjs typeorm class-validator


【解决方案1】:

感谢@JayMcDoniel 的 cmets 和指导。解决方案是编辑 main.ts 并添加来自 class-validator 模块的 useContainer 以指示它使用 nestjs 容器。

import { ValidationPipe } from '@nestjs/common';
import { NestFactory } from '@nestjs/core';
import { useContainer } from 'class-validator';

import { AppModule } from './app.module';
import { CommonModule } from './common/common.module';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  app.useGlobalPipes(
    new ValidationPipe({
      whitelist: true,
      transform: true,
    }),
  );
  useContainer(app.select(CommonModule), { fallbackOnErrors: true });
  await app.listen(3000);
}
bootstrap();

【讨论】:

    猜你喜欢
    • 2021-08-05
    • 2021-01-07
    • 2019-03-05
    • 1970-01-01
    • 2013-01-04
    • 1970-01-01
    • 2020-04-19
    • 2017-07-27
    • 2021-09-08
    相关资源
    最近更新 更多