0. Overview

Examples

  • ApiProperty 데코레이터의 type 옵션을 통해 리스트 객체를 지정한다.
export class OrderRequestDto {
  @ApiProperty({
    description: 'list of order',
    type: [OrderDto],	// List 로 받을 객체의 타입을 선언해준다.
  })
  ...
  data: OrderDto[];
}

Spec

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

1. Preface

Swagger 는 API 를 테스트하고 문서화 하는 것에 최고의 도구라고 생각합니다. 특히 가장 큰 장점은 소스코드 레벨에서 문서화를 할 수 있는 것입니다. API 툴은 Postman 이나 Insomnia 와 같은 전용 툴들도 많지만, 귀찮고 시간도 많이 걸리는 문서화 작업을 코드 레벨에서 할 수 있는 것은 정말 큰 장점입니다.

API 의 Request, Response 가 어떤 타입인지 표시할 수 있고, 또 어떤 데이터가 필요한지 설명과 샘플 데이터도 기록해서 나타낼 수 있습니다.

이번에 새롭게 개발한 API 에서는 Request Body 에 List 형식의 데이터를 받게 되었는데요. 이 List 형식의 데이터를 Swagger 에서 어떻게 표시할 수 있는지 정리해보도록 하겠습니다.

2. Problem

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 에 표시할 수 있을까요?

3. How to solve

찾아보니 해결 방법은 간단했습니다. 이번 문제는 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
    }
  ]
}

4. Conclusion

Swagger 에서 List 형식의 Request Body 예시를 정확하게 표시하는 방법에 대해 정리해 보았습니다. @ApiPropertytype 옵션 설정으로 간단하게 할 수 있었습니다. 기회가 된다면 Swagger 를 이용해 API 문서화를 할 수 있는 더 좋은 방법에 대해 알아보고 정리해보도록 하겠습니다.


profile
Tokyo Dev

0개의 댓글