Nestjs 프로젝트에 Swagger 도입하기

학구·2021년 3월 1일
0
post-thumbnail

프로젝트의 사이즈가 커질수록 REST API의 수가 정말 어마 무시하게 많아지는데요, API가 문서화되지 않는다면 어떤 API들이 있었나 헷갈려서 소스코드 이곳저곳을 뒤적거리는 일이 발생할 수 있습니다.

그렇다고 따로 문서에 엔드 포인트, 파라미터, 결괏값 등을 적어놓자니 여간 귀찮은 작업이 아닌데요
이런 고민들을 해결해 주는 Swagger를 소개해드립니다!

Swagger란?

스웨거(Swagger)는 개발자가 REST 웹 서비스를 설계, 빌드, 문서화, 소비하는 일을 도와주는 대형 도구 생태계의 지원을 받는 오픈 소스 소프트웨어 프레임워크이다. 대부분의 사용자들은 스웨거 UI 도구를 통해 스웨거를 식별하며 스웨거 툴셋에는 자동화된 문서화, 코드 생성, 테스트 케이스 생성 지원이 포함된다.

Swagger 설치

먼저 프로젝트에 swagger를 설치합니다

$ yarn add @nestjs/swagger swagger-ui-express

Swagger를 Nest에 추가 해주기

main.ts에서 아래와 같이 SwaggerModule와 DocumentBuilder를 app에 탑재해 주시면 됩니다.

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

async function bootstrap() {
  const app = await NestFactory.create(AppModule);

  const config = new DocumentBuilder()
      .setTitle('API DOCS EXAMPLE!')
      .setDescription('API 문서입니다.')
      .setVersion('0.0.1')
      .addBearerAuth
        { type: 'http', scheme: 'bearer', bearerFormat: 'Token' },
        'access-token',
      )
      .build();

  const document = SwaggerModule.createDocument(app, config);
  SwaggerModule.setup('api', app, document);

  await app.listen(8080);
  
}

bootstrap();

이제 Swagger를 사용할 준비는 끝났습니다!
addBearerAuth 옵션은 AuthGuar를 사용할 경우에 추가해 주시면 API 문서 페이지에서 Authorization 버튼이 생성됩니다.
저는 8080포트를 사용하기 때문에 http://localhost:8080/api 경로로 이동해보겠습니다.

짠~ 이렇게 API의 엔드 포인트들이 UI로 문서화돼서 나오고 있는 게 보이실 겁니다
하지만 아직 설명(description), 파라미터(parameters), 바디(Request body), 응답(Response) 등이 비어있는 상태인걸 알 수 있는데요 비어있는 부분들을 한번 채워보겠습니다 :)

엔드 포인트 Status별로 설명 추가해주기

controller에 Response 별로 설명을 추가해 보겠습니다.

import {
  ApiResponse,
  ApiOkResponse,
  ApiUnauthorizedResponse,
} from '@nestjs/swagger';

@Post('/register')
@ApiResponse({
  description: '회원가입 API',
})
@ApiBody({ type: CreateUserDTO })
register(@Body() userData: CreateUserDTO) {
  return this.userService.register(userData);
}

@UseGuards(AuthGuard('local'))
@Post('/login')
@ApiOkResponse({
    description: '유저 로그인',
})
@ApiUnauthorizedResponse({ description: 'Invalid Credential' })
  login(@Body() userData: LoginUserDTO): Promise<any> {
  return this.userService.login(userData);
}

ApiResponse, ApiOkResponse, ApiUnauthorizedResponse 3가지를 swagger에서 가져와서 각각의 API메서드 상단에 어노테이션을 달아줍니다.

@ApiCreatedResponse 는 생성완료를 알리는 status 201코드에 대한 설정입니다.

@ApiOkResponse 는 status 200코드에 대한 설정입니다.

@ApiUnauthorizedResponse 는 401코드에 대한 설정입니다.

이렇게 정해진 status 데코레이터를 사용해도 되지만 커스텀 하게 사용하실 경우

@ApiResponse 는 status옵션값을 추가해서 원하시는 status코드로 추가해주실 수 있습니다. 넣지 않을경우 undefined로 뜨기때문에 꼭 추가해주셔야합니다.

추가로 API DOCS 화면에서 하단에 Schema 부분에 내용이 채워지게 하려면
@ApiBody 데코레이터에 type 옵션으로 DTO를 추가해 주셔야 합니다!

프로퍼티 정보 추가해주기

이번에는 DTO부분에 Request body 프로퍼티를 추가해 보겠습니다.

import { IsString } from 'class-validator';
import { ApiProperty } from '@nestjs/swagger';

export class CreateUserDTO {
  
  @IsString()
  @ApiProperty({ type: String, description: '유저 ID' })
  readonly user_id: string;

  @IsString()
  @ApiProperty({ type: String, description: '유저 Password' })
  readonly password: string;

  @IsString()
  @ApiProperty({ type: String, description: '유저 Nickname' })
  readonly nickname: string;
  
}

완성된 register API의 문서의 모습입니다. 텅 비어있던 처음의 모습과 비교했을 때 잘 정리되어 있죠?
'Try it out' 버튼을 클릭하시면 Postman과 같은 API 테스트를 즉시 실행해볼 수 있답니다 :)

Bearer Auth 보안 설정 해주기

다음으로는 JWT AuthGuard로 Bearer 토큰을 필요로 하는 API를 설정해보도록 하겠습니다.
저 같은 경우에는 auth.controller에 /temp 라는 엔드 포인트에 @UseGuards(AuthGuard('jwt')) 어노테이션이 붙어있는 API를 기준으로 해보겠습니다.

  @ApiBearerAuth() //이부분이 추가되었습니다.
  @Get('/temp')
  @UseGuards(AuthGuard('jwt'))
  tempAuth() {
    return { auth: 'works' };
  }

@ApiBearerAuth()를 달아주면 Swagger 문서에서 자물쇠가 잠기며 Bearer 토큰이 필요한 API 임을 알려주게 됩니다!

이것으로 Swagger에 대한 간단한 설명을 마치겠습니다.
더 자세한 내용은 Swagger 공식 문서를 참고해보시면 좋을 것 같습니다. 감사합니다 :)

profile
불꽃남자

0개의 댓글