최근 NestJS 기반의 API 서버를 개발하기 위해 스터디 중입니다.
기존에는 node.js로 개발해서 운영중이고요. node만 하면서 이런건 어떻게 좀 안될까 싶었던 많은 부분들이 Nest에서 해결되어 있네요.
체계적으로 개발할 수 있다는 느낌이 들어 좋아보입니다.
스터디를 하던중에 공통의 컨트롤러와 서비스를 이용해서 다양한 모델에 적용하는 공통 모듈을 개발해보려고 이것 저것 시도해보고 있습니다.
그러다 구글링 중에 base crud란 검색어 결과에 저와 비슷한 고민을 한 사람들이 꽤 있고 구현물도 좀 있더군요.
개념은 별거 아닙니다. 기본적인 CRUD를 수행하는 공통의 컨트롤러와 서비스를 만들고 새로운 DB 컬랙션이 필요할 때마다 이 공통모듈을 확장해서 이용하는거죠.
최근 참고 하고 있는 자료가 https://github.com/xavism/nestjs-generic-crud 입니다.
잘 되네요...^^
근데 문제가 있습니다.
베이스 컨트롤러에서 ValidationPipe가 동작을 안하는 문제가 있어 조언을 구힙니다.
구현한 베이스 컨트롤러의 내용은 아래와 같습니다.
@Controller()
export class BaseController<T extends BaseEntity>{
constructor(private readonly baseService: BaseService<T>) { }
@Post()
@UsePipes(new ValidationPipe({
whitelist: true, // decorator(@)가 없는 속성이 들어오면 해당 속성은 제거하고 받아들입니다.
forbidNonWhitelisted: false, // DTO에 정의되지 않은 값이 넘어오면 request 자체를 막습니다.
transform: true,
}))
async create(@Body() doc: T) {
console.log(typeof User);
console.log(typeof doc);
console.log(doc);
// return this.baseService.create(doc);
}
}
UserController에서 BaseController를 상속하면 기본 CRUD를 바로 이용하겠다는 개념인데 Post 데이터를 전송하면 파이프를 타지않고 create()가 바로 호출되어 버립니다.
혹시나 해서 doc의 타입을 임의로 User로 변경해보니 바로 파이프를 타더군요.
async create(@Body() doc: User) <-이런식으로요.
결국 데코레이터에 정확한 클래스 타입을 적어줘야 파이프를 탄다는 것 같습니다.
이런 경우 어떻게 수정을 해줘야 할까요?
전문가분들의 조언 부탁드립니다. 꾸벅
저라면 @UsePipes(new ValidationPipe({...})) 부분을 base에서 제거한 뒤 custom decorator로 빼서 child class에서 재사용할 거 같네요.
하나 조심하셔야될게 자바스크립트의 class 개념이 다른 프로그래밍 언어랑 많이 달라서, 여러 edge case들이 발생할 수 있습니다. 특히 NestJS 같은 프레임워크를 사용할 때요. Dependency Injection이 제대로 안되는 것부터 시작해서 별의별 문제를 다 겪어봤네요. 그런 케이스의 경우 완전 엉뚱한 에러메시지 뿜는 경우가 많아서 디버깅이 좀 까다롭습니다.
답변주신 방법으로 한번 해보겠습니다.
말씀하셨던 내용 중 child class에서 재사용하신다는 내용에 대해 조금 설명해 주실 수 있으실까요?
좋은 하루 되시길 바랍니다.