typescript - NestJS DTO-klasse angi kjørerekkefølge for class-validator og class-transformer
Finnes det en måte å angi kjørerekkefølgen for dekoratører når man beskriver en DTO-klasse i NestJS ved bruk av class-validator og class-transformer-pakkene?
Følgende kode feiler når verdien av foo settes til null med feilen:
Forventet en streng, men mottok null
@IsOptional()
@IsString()
@IsByteLength(1, 2048)
@Transform(({ value }) => validator.trim(value))
@Transform(({ value }) => validator.stripLow(value))
foo: string;
Selv om jeg har en isString-dekorator som skal sjekke at det faktisk ble sendt en streng og allerede må feile for å ikke overføre utførelsen til @Transform-dekoratorene, så feilet den ikke.
Svar #1
Class-Validator fungerer basert på klasser. Forespørselsdata som kommer inn til serveren er bare vanlige JSON-objekter til å begynne med. For å endre denne oppførselen, må Nest først kalle plainToClass fra class-validator hvis du bruker dens ValidationPipe. På grunn av dette, får @Transform()-dekoratørene forrang over de andre class-validator-dekoratørene, og blir behandlet først. Du kan omgå dette ved å bruke flere pipes, eller muligens ved å gi standardverdier til @Transform()-dekoratøren, men det som skjer er den tilsiktede effekten.
Svar #2
Kontroller @Transfrom og Validator-dekoratørens utførelsesrekkefølge med 2 ValidationPipe
main.ts
import { ValidationPipe } from '@nestjs/common';
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
app.useGlobalPipes(
new ValidationPipe({
whitelist: true,
}),
new ValidationPipe({
transform: true,
transformOptions: { groups: ['transform'] },
}),
);
await app.listen(4000);
}
bootstrap();
create-user.dto.ts
export class CreateUserDto {
@ApiProperty({
description: 'username',
minLength: 4,
maxLength: 64,
})
@Length(4, 64)
name: string;
@ApiProperty({
description: 'password',
minLength: 4,
maxLength: 64,
})
@Length(6, 64)
@Transform(({ value }: { value: string }) => hashSync(value), {
groups: ['transform'],
})
password: string;
}
Dette vil kjøre @Length først, og deretter @Transform.
Oversettelse med Deepl
