서버/nodejs
[nestjs] 스웨거 사용시 주의사항 - 순환참조 에러
멍개.
2022. 8. 29. 07:50
nestjs에서 스웨거 사용시 주의사항을 살펴보겠습니다.
스웨거를 사용하다보면 다음과 같은 에러가 발생할 수 있습니다.
/Users/jeongtaepark/Desktop/node_modules/@nestjs/swagger/dist/services/schema-object-factory.js:170
throw new Error(`A circular dependency has been detected (property key: "${key}"). Please, make sure that each side of a bidirectional relationships are using lazy resolvers ("type: () => ClassType").`);
^
Error: A circular dependency has been detected (property key: "user"). Please, make sure that each side of a bidirectional relationships are using lazy resolvers ("type: () => ClassType").
at SchemaObjectFactory.createNotBuiltInTypeReference (/Users/jeongtaepark/Desktop/node_modules/@nestjs/swagger/dist/services/schema-object-factory.js:170:19)
at SchemaObjectFactory.createSchemaMetadata (/Users/jeongtaepark/Desktop/node_modules/@nestjs/swagger/dist/services/schema-object-factory.js:280:25)
at SchemaObjectFactory.mergePropertyWithMetadata (/Users/jeongtaepark/Desktop/node_modules/@nestjs/swagger/dist/services/schema-object-factory.js:122:21)
at /Users/jeongtaepark/Desktop/node_modules/@nestjs/swagger/dist/services/schema-object-factory.js:79:35
at Array.map (<anonymous>)
at SchemaObjectFactory.extractPropertiesFromType (/Users/jeongtaepark/Desktop/node_modules/@nestjs/swagger/dist/services/schema-object-factory.js:78:52)
at SchemaObjectFactory.createQueryOrParamSchema (/Users/jeongtaepark/Desktop/node_modules/@nestjs/swagger/dist/services/schema-object-factory.js:57:45)
at /Users/jeongtaepark/Desktop/node_modules/@nestjs/swagger/dist/services/schema-object-factory.js:31:29
at Array.map (<anonymous>)
at SchemaObjectFactory.createFromModel (/Users/jeongtaepark/Desktop/node_modules/@nestjs/swagger/dist/services/schema-object-factory.js:20:45)
해당 에러가 발생하는 케이스를 만들어보겠습니다.
예를 들어서 유저와 게시글 관계를 정의할 때 다음과 같이 데이터를 모델링합니다.
▶ 유저 DTO
import { ApiProperty } from "@nestjs/swagger";
import { PostDto } from "./post.dto";
export class UserDto {
@ApiProperty({ type : Number })
id: number;
@ApiProperty({ type : String })
name: string;
@ApiProperty({ type : [PostDto] })
posts: [PostDto];
}
유저는 다수의 게시글을 가질 수 있습니다.
▶ 게시글 DTO
import { ApiProperty } from "@nestjs/swagger";
import { UserDto } from "./user.dto";
export class PostDto {
@ApiProperty({ type : Number })
id: number;
@ApiProperty({ type : String })
title: string;
@ApiProperty({ type : UserDto })
user: UserDto;
}
하나의 게시글은 하나의 유저를 가집니다.
이때 user와 post는 서로 순환참조 관계를 가집니다.
· 해결방법
스웨거의 ApiProperty는 이런 순환참조를 대비하여 lazy loading을 이용하합니다. 바로 @ApiProperty는 type을 전달할 때 함수의 반환값을 이용합니다.
▶ 유저 DTO
import { ApiProperty } from "@nestjs/swagger";
import { PostDto } from "./post.dto";
export class UserDto {
@ApiProperty({ type : Number })
id: number;
@ApiProperty({ type : String })
name: string;
@ApiProperty({ type : () => [PostDto] })
posts: [PostDto];
}
▶ 게시글 DTO
import { ApiProperty } from "@nestjs/swagger";
import { UserDto } from "./user.dto";
export class PostDto {
@ApiProperty({ type : Number })
id: number;
@ApiProperty({ type : String })
title: string;
@ApiProperty({ type : () => UserDto })
user: UserDto;
}
함수의 반환값으로 타입을 전달하면 lazy loading이 되기 때문에 스웨거 로드가 정상적으로 이루어집니다.