이 문제를 해결하려 최근들어 가장 머리를 쥐어뜯었던 것 같다.
이틀가량 문제해결과 포스팅준비에 시간을 쏟았다는 Tmi...
우선 어떤 상황인지부터 알아보자.
쿼리스트링으로 구독여부를 Boolean타입으로해서 해당 DTO를 파라미터로 넘겨줘야 하는 상황이었다.
처음에 보고 금방 개발할 수 있겠다 싶었는데 Boolean타입이 이상하게 찍히기 시작했다.
분명 사진처럼 Boolean으로 타입 지정해줬는데 혹시나해서 typeof 로 console을 한번 찍어보기로 했다.
어라.. dto타입이 string으로 나오는걸 확인했다.
query string은 항상 string 타입으로 요청이 들어오기 때문에 transform을 통해 타입 변환을 해줘야 했다.
ValidationPipe설정을 바꿔줘야지 데이터 타입이 변환된다고 해서 바꿔주었다.
transform를 true로 설정하면 들어오는 true데이터가 자동으로 예상 데이터 유형으로 변환됩니다. 예를 들어 숫자를 예상하는 유효성 검사 규칙이 있지만 들어오는 데이터가 숫자로 구문 분석할 수 있는 문자열인 경우 ValidationPipe는 자동으로 문자열을 숫자로 변환합니다.
- ChatGPT
main.ts에서 ValidationPipe() 설정들을 다음과 같이 바꿔주었다.
이렇게 바꿔주고나서 코드를 돌려봤더니 Boolean으로 나오긴하지만
false로 요청을 해도 console을 찍어보면 항상 true가 반환되었다.
방금 적용한 enableImplicitConversion 옵션은 말 그대로 자바스크립트의 암묵적 형변환을 적용한다는 뜻이다.
따라서, 해당 옵션이 켜진 상태에서는 string 타입인 query string을 boolean으로 변환하면서 전부true가 될 수 밖에 없었던 것이다.
그래서 결론은 커스텀 데코레이터를 사용하기로 했다.
import { applyDecorators } from "@nestjs/common";
import { Transform } from "class-transformer";
import { IsBoolean as OriginalIsBoolean } from "class-validator";
function ToBoolean() {
const toPlain = Transform(
({ value }) => {
return value;
},
{
toPlainOnly: true,
},
);
const toClass = (target: any, key: string) => {
return Transform(
({ obj }) => {
return valueToBoolean(obj[key]);
},
{
toClassOnly: true,
},
)(target, key);
};
return function (target: any, key: string) {
toPlain(target, key);
toClass(target, key);
};
}
function valueToBoolean(value: any) {
if (value === null || value === undefined) {
return undefined;
}
if (typeof value === 'boolean') {
return value;
}
if (['true', 'on', 'yes', '1'].includes(value.toLowerCase())) {
return true;
}
if (['false', 'off', 'no', '0'].includes(value.toLowerCase())) {
return false;
}
return value;
}
해당 커스텀 데코레이터 코드를 추가시켜주고 Dto에서 @ToBoolean() 데코레이터를 추가해주면 된다.
위에서 구현한 @ToBoolean 데코레이터는 Boolean 또는 string 값을 boolean 타입으로 명시적으로 변환을 해주고
Boolean으로 인식되지 않는 값일 경우 해당 string 값을 그대로 반환한다.
기존 코드에서 검증을 해보면 "true", "false"는 Boolean으로 변환이 되었기때매 통과가 되고
Boolean이 아닌값은 기존의 string 값이 전달 되기때매 검증을 통과하지 못하는걸 확인하게 되었다.
이제 쿼리스트링에서도 파라미터값으로 Boolean을 사용할 수 있게 되었다..!
'Web > NestJS' 카테고리의 다른 글
[NestJS] DB커넥션을 최소화하고 Service부에 부하를 줘야하는 이유. (0) | 2023.03.27 |
---|---|
[Nest.JS] @Param() 사용 시 왜 경로를 지정해 주는걸까? (0) | 2023.03.03 |
[Nest.JS] Error "require statement not part of import statement." 해결 방법 (0) | 2023.02.27 |
[Nest.JS] Promise { <pending> } 해결 방법 (0) | 2023.02.23 |
[Nest.JS] 순환종속성(Circular Dependency) 해결 "Use forwardRef() to avoid it." (0) | 2023.02.21 |