삼촌samchon이라는 개발자가 만든 라이브러리를 알게 되었다. 정의된 타입을 기준으로 유효성검사가 끝난다니..! 이전엔 유효성검사를 위해 @IsIn
등의 class-validator
라이브러리 함수로 여기 저기를 장식해야했는데, 조금 더 짧은 코드를 작성할 수 있는 것인가...!
현실과 이상의 차이
삼촌께서는 nestia
라는 명칭으로 플러그인과 함께 nestjs
를 덮어썼는데, 새로운 장식(데코레이터)을 써야하는 것은 내게 불만이었다. 그런데 기존 코드까지 많은 변경이 필요하다면, 내 기준에선 도입할 이유가 없었다.
왜냐하면 나는 TS에서 디버깅하기 불편한 데코레이터라는 기능을 선호하지 않는데다가, JS는 성능보단 빠른 코드작성을 위해 사용하고 있다. node에서 유효성 검사를 몇 천배 더 빠르게 해봐야, 게임처럼 연산비용이 높은 서버로 활용하기는 부족하기 때문. 성능개선이 핵심이라면, 다른 언어를 선택하거나, 웹어셈블리를 도입하는 게 낫다.
아무튼 기존 앱의 수정은 최소화하고, TSON
을 적용하고 싶었다. 우선 useGlobalPipe
의 객체를 대체해보기로 결정하고, 조금 만지작거려 봤다.
일단 TSON
은 제네릭을 기반으로 유효성검사기가 컴파일되기 때문에, 그 부분을 일반파라미터로 받을 순 없었다. 다음 시도는 실패로 끝났다.
import { ArgumentMetadata, PipeTransform } from '@nestjs/common';
import { plainToInstance } from 'class-transformer';
import TSON from 'typescript-json';
export class TSONPipe implements PipeTransform {
transform(value: any, { metatype }: ArgumentMetadata): any {
const inst = plainToInstance(metatype, value);
// 아래 코드를 보자.
// typeof metatype은 object이므로, 원하던 결과가 나오지 않는다.
// TSON.assert<metatype>은 metatype이 타입이 아니기 때문에, 컴파일 실패
// {[metatype]: TSON.createAssert<MetaType>() } 같은 형태로 맵핑된 오브젝트에서 호출은 가능은 할 것이다.
TSON.assert<typeof metatype>(inst);
return inst;
}
}
아직 Typia(TSON)는 generic parameter를 인식하지 못한다
런타임에서 동적으로 validate
/assert
함수를 생성해주는 것은 TSON
의 작동방식이 아니란 것을 깨닫고, 다음 코드처럼 데코레이터를 만들어봤다. 아래 코드는 뜻밖의 이유로 실패로 끝나버렸다.
import { Type } from '@nestjs/common';
import TSON from 'typescript-json';
export type TGreeting = 'hello' | 'hi';
@CheckWithTSON<GreetingDto>()
export class GreetingDto {
greeting?: TGreeting;
}
function CheckWithTSON<T>(strategy: 'assert' | 'validate' = 'assert') {
let checkMethod;
switch (strategy) {
case 'assert':
checkMethod = TSON.createAssert<T>();
break;
case 'validate':
checkMethod = TSON.createValidate<T>();
break;
}
return (klass: any) =>
class extends klass {
__CheckWithTSON() {
return checkMethod(this);
}
} as Type<T> & { __CheckWithTSON: VoidFunction };
}
실패 이유는, 다름아닌 TSON.createAssert<T>()
에서 T
를 제네릭파라미터로 컴파일해내지는 못한다는 것이다. T
의 자리에는 반드시 정적 타입이 들어와야 컴파일 된다. 이러한 부분 때문에 생각보다는 코드가 많이 줄어들지 않았고, 아쉬운 부분이라고 생각이 들었다. 그래도 언젠가는 이러한 약점은 개선될 것이다. 내가 오픈소스에 기여해보는 것도 방법이겠지만, 일단은 그날이 빨리 오길 기도하며 기다리겠다.
'IT' 카테고리의 다른 글
Nest.js와 TypeORM 그리고 Prisma ORM (4) | 2023.01.29 |
---|---|
PostgreSQL에 사용자와 권한 추가하기(CREATE USER, GRANT PERMISSIONS) (0) | 2023.01.28 |
Node Engine 수정하기 (0) | 2022.12.10 |
Android emulator에서 Push notification이 수신되지 않을 때 (0) | 2022.12.04 |
[Refactoring 2판]에 대한 내 생각과 비판 (0) | 2022.11.13 |