export class DecideProductReqListRequest {
@ApiProperty()
@IsNumber()
productReqListId: number;
@ApiProperty()
@IsString()
status: string;
@ApiProperty()
@IsString()
reason?: string;
}
나는 이 Request DTO의 status 의 값이 'Approved, Rejected, Delayed' 이 셋 중 하나만 입력되게 하고 싶다.
employee.service.ts
async decideProductReqList(
employeeId: number,
request: DecideProductReqListRequest,
): Promise<ProductReqListEntity> {
const productReqInfo = await this.productReqListRepository.findOne({
where: { id: request.productReqListId },
relations: ['user', 'employee'],
});
...
if (
request.status != 'Approved' &&
request.status != 'Rejected' &&
request.status != 'Delayed'
) {
throw new BadRequestException('status 값이 올바르지 않습니다.');
}
}
처음에는 Service 단에서 throw new BadRequestException
으로 잡았다. 근데 이렇게 하면 controller 를 넘어서 service 의 맨 마지막 문장까지 와서야 잡히게 된다. 내가 원하는건 request 에 내가 원하는 값이 들어오지 않으면 튕기는 것이다.
그래서 여태 써오던 class-validator 에서 request 를 잡아줄 데코레이터가 있는지 검색해서 @IsIn
을 찾았다.
export class DecideProductReqListRequest {
@ApiProperty()
@IsNumber()
productReqListId: number;
@ApiProperty()
@IsIn(['Approved', 'Rejected', 'Delayed'])
status: string;
@ApiProperty()
@IsString()
reason?: string;
}
근데 적용이 안된다. 뭐가 문제일지 생각을 해보다가, 설마 다른 class-validator 도 적용이 안되는건가 하고 class-validator 적용하는 방법을 찾아봤는데, 유효성 검사를 전역으로 적용하려면 main.ts 의 코드에 추가해줄 것이 있었다.
main.ts
async function bootstrap() {
const app = await NestFactory.create(AppModule);
app.useGlobalPipes(new ValidationPipe());
...
await app.listen(3000);
}
bootstrap();
app.useGlobalPipes(new ValidationPipe());
main.ts 를 수정하고 status 에 원하지 않는 값을 넣어보니 class-validator 가 정상적으로 동작했다.
{
"statusCode": 400,
"message": [
"status must be one of the following values: Approved, Rejected, Delayed"
],
"error": "Bad Request"
}
여태 유효성이 검증되는지도 확인 안해봤었구만..