-
NestJS Response Dto에 generic을 swagger ApiProperty 데코레이터에 사용하기Nest.js 2024. 6. 4. 14:34728x90
// pagination response { list:T[]; page:number; totalPage:number; } // cursor pagination response { list:T[]; cursor:{ after: string; }; count: number; next: string; }
보통 pagiantion이 필요하거나 cursor pagination이 필요한 api는 위와 같은 동일한 response형식을 가질것이다.
// feed-get-all-res-dto.ts import { ApiProperty } from '@nestjs/swagger'; import { FeedResDto } from './feed-res.dto'; export class FeedGetAllResDto { @ApiProperty({ nullable: false, type: [FeedResDto], }) list!: FeedResDto[]; @ApiProperty({ nullable: false, }) page!: number; @ApiProperty({ nullable: false, }) totalPage!: number; }
그렇다면 이러한 형식의 똑같은 Response dto가 여러개가 생성될텐데 feedAllResDto, notificationAllResDto, ChatAllResDto ... 굉장히 비효율적인 중복코드이다. 그래서 하나의 pagination-res-dto를 만들어서 제네릭을 이용하여 하나로 통합해서 사용하면 될것 같았다. 하지만 이것은 내 생각대로 동작하지 않았다.
export class PaginationResDto<T> { @ApiProperty({ nullable: false, type: [T], }) list!: T[]; @ApiProperty({ nullable: false, }) page!: number; @ApiProperty({ nullable: false, }) totalPage!: number; }
'T' only refers to a type, but is being used as a value here
swagger를 만들어주는 @ApiProperty 데코레이터에서 T의 타입들을 보여주는 type: [T]에서 위와 같은 에러가 발생했다.
이게 무슨 뜻이냐 T는 오직 참조 타입인데 여기엔 value값이 와야 된다는것이다.
즉 타입체커 환경에서 사용하는것들이 올 수 있는게 아니라 런타임환경에서 사용 할 수 있는것들이 와야 된다는것이다. function, class ...등해당 문제를 해결하기 위해 사용 되는것이 Mixin이다
Mixin
믹스인은 다른 클래스의 상위 클래스가 아니더라도 다른 클래스에서 사용할 수 있는 메서드를 포함하는 클래스입니다.
즉, 믹스인은 특정 동작을 구현하는 메서드를 제공하지만 우리는 이를 단독으로 사용하지 않고 다른 클래스에 동작을 추가하는 데 사용합니다.// basic-pagination-res.dto.ts import { mixin } from '@nestjs/common'; import { ApiProperty } from '@nestjs/swagger'; type Constructor<T = object> = new (...args: any[]) => T; export function withBasicPaginationResponse<T extends Constructor>(Base: T) { class BasicPaginationResDto { @ApiProperty({ nullable: false, type: [Base], }) list!: T[]; @ApiProperty({ nullable: false, }) page!: number; @ApiProperty({ nullable: false, }) totalPage!: number; } return mixin(BasicPaginationResDto); }
@ApiOkResponse({ description: '피드 조회 성공', type: () => withBasicPaginationResponse(FeedResDto), }),
Reference
https://www.typescriptlang.org/docs/handbook/mixins.html
https://www.inextenso.dev/how-to-generate-generic-dtos-with-nestjs-and-swagger
https://github.com/nestjs/nest/issues/4180
nestjs issue번호 4180를 확인 해보면 "카밀형님 피셜로 mixin은 사용해도 되지만 더이상 필요가 없다. 그래서 공식문서에서 제거되었다고 되어있다."
728x90'Nest.js' 카테고리의 다른 글
메일 전송시 Promise.allSettled 사용하기 (0) 2024.06.08 NestJS에서 repository의 insert메서드로 유동적으로 데이터 생성하기 (2) 2024.06.04 cookie-option secure: true 옵션 사용시 Safari localhost에서 쿠키 저장이 안되는 문제 (0) 2024.05.23 NestJS에서 nest-cli로 실행 시킬때 src폴더 외 루트 경로 인식 못할때 (0) 2024.04.17 NestJS에서 yarn-berry로 생성 후 발생하던 문제 (0) 2024.04.07