[Nest.js] swagger 데코레이터 - 4 (DTO/모델)

SMALL

1. @ApiProperty()

- 용도: DTO나 엔티티의 속성을 Swagger 문서에 정의

class CreatePostDto {
  @ApiProperty({
    description: '게시글 제목',         // 속성 설명
    example: '안녕하세요',             // 예시 값
    required: true,                   // 필수 여부
    type: String,                     // 타입
    maxLength: 100,                   // 최대 길이
    default: 'New Post',             // 기본값
    enum: ['DRAFT', 'PUBLISHED'],     // enum 타입인 경우
    isArray: false,                   // 배열 여부
    minimum: 0,                       // 숫자 최소값 (number 타입)
    maximum: 100,                     // 숫자 최대값 (number 타입)
  })
  title: string;

  @ApiProperty({
    type: 'array',                    // 배열 타입 정의
    items: {                          // 배열 아이템 타입
      type: 'string',
      enum: ['TAG1', 'TAG2', 'TAG3']
    }
  })
  tags: string[];
}

 

2. @ApiPropertyOptional()

- 용도: 선택적(optional) 속성을 정의

class UpdatePostDto {
  @ApiPropertyOptional({
    description: '수정할 제목',
    example: '수정된 제목'
  })
  title?: string;

  @ApiPropertyOptional({
    description: '수정할 내용',
    example: '수정된 내용입니다.'
  })
  content?: string;
}

 

3. @ApiHideProperty()

- 용도: Swagger 문서에서 특정 속성을 숨김

class UserDto {
  @ApiProperty()
  email: string;

  @ApiHideProperty()  // 비밀번호는 문서에서 제외
  password: string;
}

 

** 사용 예시

// user.entity.ts
class User {
  @ApiProperty({
    description: '사용자 고유 식별자',
    example: 1
  })
  id: number;

  @ApiProperty({
    description: '사용자 이메일',
    example: 'user@example.com',
    format: 'email'
  })
  email: string;

  @ApiHideProperty()
  password: string;

  @ApiProperty({
    description: '사용자 역할',
    enum: UserRole,
    default: UserRole.USER,
    example: UserRole.USER
  })
  role: UserRole;
}

// create-post.dto.ts
class CreatePostDto {
  @ApiProperty({
    description: '게시글 제목',
    minLength: 5,
    maxLength: 100,
    example: '첫 번째 게시글'
  })
  title: string;

  @ApiProperty({
    description: '게시글 내용',
    example: '게시글 내용입니다.'
  })
  content: string;

  @ApiPropertyOptional({
    description: '게시글 태그',
    isArray: true,
    example: ['태그1', '태그2']
  })
  tags?: string[];

  @ApiProperty({
    description: '게시글 상태',
    enum: PostStatus,
    default: PostStatus.DRAFT,
    example: PostStatus.DRAFT
  })
  status: PostStatus;

  @ApiProperty({
    description: '첨부 파일',
    type: 'array',
    items: {
      type: 'object',
      properties: {
        filename: {
          type: 'string',
          example: 'image.jpg'
        },
        size: {
          type: 'number',
          example: 1024
        }
      }
    }
  })
  attachments: Array<{
    filename: string;
    size: number;
  }>;
}

// post-response.dto.ts
class PostResponseDto {
  @ApiProperty({
    description: '게시글 ID',
    example: 1
  })
  id: number;

  @ApiProperty({
    description: '작성자 정보',
    type: () => User  // 순환 참조를 피하기 위한 타입 함수
  })
  author: User;

  @ApiProperty({
    description: '생성 일시',
    example: '2024-01-01T00:00:00Z'
  })
  createdAt: Date;

  @ApiPropertyOptional({
    description: '수정 일시',
    example: '2024-01-02T00:00:00Z'
  })
  updatedAt?: Date;
}
LIST