swagger 자동화

노누리·2022년 6월 17일
0

지난 포스팅에서 swagger 문서를 작성하는 법을 설명했다.

swagger 사용하기

yaml 파일을 작성하면 라우터가 변경되었거나 response 값이 변경되는 등 api 명세서가 바뀌게 되는 경우에 일일이 바꿔줘야하는 불편함이 있었다.

그래서 swagger 자동화 방법을 찾았다.

모듈 설치

npm install --save @nestjs/swagger swagger-ui-express

위 모듈을 설치한 후에는

  • main.ts
  • swagger.ts

파일을 수정 및 생성을 해주고 본격적으로 swagger 자동화를 위한 데코레이터를 추가하면 된다.

main.ts

import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import * as config from 'config';
import { Logger } from '@nestjs/common';
import { setupSwagger } from 'src/util/swagger';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  const Config = config.get('server');
  const port = Config.port;
  setupSwagger(app);

  await app.listen(port);

  Logger.log(`hello welcome ${port}`);
}
bootstrap();

우선 main.ts 파일에 setupSwagger(app)이라는 코드를 추가한다. 이때 setupSwagger는 추가로 만들 swagger.ts파일을 가리킨다.

swagger.ts

import { INestApplication } from '@nestjs/common';
import { SwaggerModule, DocumentBuilder } from '@nestjs/swagger';

/**
 * Swagger 세팅
 *
 * @param {INestApplication} app
 */
export function setupSwagger(app: INestApplication): void {
  const options = new DocumentBuilder()
    .setTitle('Nestjs Swagger Test')
    .setDescription('test')
    .setVersion('1.0.0')
    .addBearerAuth(
      {
        type: 'http',
        scheme: 'bearer',
        name: 'JWT',
        in: 'header',
      },
      'access-token',
    )
    .build();

  const document = SwaggerModule.createDocument(app, options);
  SwaggerModule.setup('swagger', app, document);
}

위의 코드처럼 swagger.ts을 만들어준다. swagger 문서를 위한 기초 세팅이라고 생각하면 된다. title을 정해주고, version, 인증 방식 등 설정해주고, 마지막에 어떤 라우터에 설정할 것인지 url도 설정해준다.

데코레이터 설정해주기

swagger 사용을 위한 기초 세팅은 끝났다. 이제 각 controller와 entity등에 데코레이터를 추가하여 swagger 문서에 올라갈 수 있도록 작업해준다.

board.entity.ts

import { ApiProperty } from '@nestjs/swagger';
import { BaseEntity, Column, Entity, PrimaryGeneratedColumn } from 'typeorm';

@Entity()
export class Board extends BaseEntity {
  @PrimaryGeneratedColumn()
  @ApiProperty({ description: 'id' })
  id!: number;

  @Column()
  @ApiProperty({ description: '게시글 제목' })
  title!: string;

  @Column()
  @ApiProperty({ description: '게시글 설명' })
  description!: string;
}

위 코드에서 보면 알 수 있듯이 @ApiProperty()를 이용하여 이러한 column이 있다는 것을 swagger에게 알려준다.

board.controller.ts

@Get()
@ApiOperation({
  summary: '게시글 전체 조회',
  description: '게시글 전체 조회',
})
@ApiResponse({ description: '조회 성공', type: Board })
getAllBoards(): Promise<Board[]> {
  return this.boardService.AllBoards();
}

@Post()
@ApiOperation({
  summary: '게시글 생성',
  description: '게시글 생성',
})
@ApiBody({ type: CreateBoardDto })
@ApiResponse({ description: '생성 성공', type: CreateBoardDto })
createBoard(@Body() boardData: CreateBoardDto): Promise<Board> {
  return this.boardService.create(boardData);
}

controller 코드에는

  • ApiOperation
  • ApiResponse
  • ApiBody

등을 이용하여 swagger에 알려준다.

이때 CreateBoardDto에도 @ApiProperty() 데코레이터를 추가해준다.

create-board.dto.ts

import { ApiProperty } from '@nestjs/swagger';

export class CreateBoardDto {
  @ApiProperty({ description: '게시글 제목' })
  readonly title: string;

  @ApiProperty({ description: '설명' })
  readonly description: string;
}

이렇게 모두 작성하고 나서 처음에 설정해준 라우터로 접속을 해보면 아래와 같은 화면이 뜬다.

본인은 localhost:5000/swagger로 접속한다.


게시글 전체 조회 api

위 사진처럼 response 형식이 Board.entity 형식으로 맞춰서 나오게 된다.


이렇게 swagger 자동화를 해주면 데코레이터를 추가해주는 것만으로도 알아서 그에 맞게 명세를 짜준다.

이전에 yaml 파일을 통째로 작성한 것보다 훨씬 효율적인 방법을 찾았다!

profile
백엔드 개발자입니다.

0개의 댓글