export class OrderRequestDto {
@ApiProperty({
description: 'list of order',
type: [OrderDto], // List 로 받을 객체의 타입을 선언해준다.
})
...
data: OrderDto[];
}
project:
framework:
- nestjs
versions:
nodejs: 14.2
typescript: 3.7
nest: 7.0
swagger: 4.5
swagger-ui-express: 4.1
class-validator: 0.12
class-transformer: 0.2
Swagger 는 API 를 테스트하고 문서화 하는 것에 최고의 도구라고 생각합니다. 특히 가장 큰 장점은 소스코드 레벨에서 문서화를 할 수 있는 것입니다. API 툴은 Postman 이나 Insomnia 와 같은 전용 툴들도 많지만, 귀찮고 시간도 많이 걸리는 문서화 작업을 코드 레벨에서 할 수 있는 것은 정말 큰 장점입니다.
API 의 Request, Response 가 어떤 타입인지 표시할 수 있고, 또 어떤 데이터가 필요한지 설명과 샘플 데이터도 기록해서 나타낼 수 있습니다.
이번에 새롭게 개발한 API 에서는 Request Body 에 List 형식의 데이터를 받게 되었는데요. 이 List 형식의 데이터를 Swagger 에서 어떻게 표시할 수 있는지 정리해보도록 하겠습니다.
Nest.js 에서 Swagger 데코레이터를 이용해 아래와 같이 Dto 를 만들었습니다.
import {ApiProperty} from '@nestjs/swagger';
import {Type} from 'class-transformer';
import {
ArrayNotEmpty,
IsArray,
IsNotEmpty,
IsString,
ValidateNested,
} from 'class-validator';
export class OrderDto {
@ApiProperty({
description: 'product no',
example: 'PN43443223',
})
@IsNotEmpty()
@IsString()
productNo: string;
@ApiProperty({
description: 'product amount',
example: '14500',
})
@IsNotEmpty()
@IsNumber()
amount: number;
}
export class OrderRequestDto {
@ApiProperty({
description: 'list of order',
})
@IsArray()
@ArrayNotEmpty()
@Type(() => OrderDto)
@ValidateNested({each: true})
data: OrderDto[];
}
그리고 Swagger 배포해서 프론트 개발자분께 API 확인을 부탁드렸는데, Request Body 타입이 이상하다는 연락이 왔습니다. 설계랑 다르게 string List 라는 것이었습니다. Swagger 를 열어보니 정말 아래와 같이 되어 있었습니다. 분명 Dto 객체를 List 로 선언했는데 (data: OrderDto[]
) 뜬금없이 "string" 이라는 표시가 되어 있었습니다.
{
"data": [
"string"
]
}
막상 Swagger 에서 동작 확인을 해보니 동작에는 아무 문제가 없었습니다. Swagger 의 예시 표시가 정확하지 않았고, 이로 인해 API 를 잘못 사용할 수 있다는 것이 가장 큰 문제였습니다. Swagger 를 API 문서 대신 사용하기도 하기에 정확한 표시를 하도록 해야 했습니다.
어떻게 해야 제대로 Dto 객체를 Swagger 에 표시할 수 있을까요?
찾아보니 해결 방법은 간단했습니다. 이번 문제는 Swagger 에 표시되는 예시만 잘못된 것입니다. 그렇기 때문에 Dto 의 설명, 예시 등을 담당하는 데코레이터 @ApiProperty
의 옵션 중 type
을 사용해서 해결할 수 있었습니다. type 옵션은 이 객체가 어떤 타입을 사용하는가를 Swagger 에 표시시켜줍니다. 따라서 아래의 코드와 같이 List 로 받을 Dto 를 type 에 넣어주면 간단하게 해결 할 수 있습니다.
export class OrderRequestDto {
@ApiProperty({
description: 'list of order',
type: [OrderDto], // List 로 받을 객체의 타입을 선언해준다.
})
@IsArray()
@ArrayNotEmpty()
@Type(() => OrderDto)
@ValidateNested({each: true})
data: OrderDto[];
}
{
"data": [
{
"productNo": "PN43443223",
"amount": 14500
}
]
}
Swagger 에서 List 형식의 Request Body 예시를 정확하게 표시하는 방법에 대해 정리해 보았습니다. @ApiProperty
의 type
옵션 설정으로 간단하게 할 수 있었습니다. 기회가 된다면 Swagger 를 이용해 API 문서화를 할 수 있는 더 좋은 방법에 대해 알아보고 정리해보도록 하겠습니다.