nestjs swagger 설정 및 옵션

양진영·2023년 2월 9일
0

nestJs

목록 보기
5/10

나는 신입 서버개발자로 일하며 내가 이렇게 이렇게 프론트로 부터 데이터를 받을수 있을까? 라고 생각해 주변 프론트개발자 분들에게 물어본적이 많다. "나 이렇게 이렇게 데이터 받고 싶은데 이런형식으로 줄수있어?" 라고 물어보며 로직을 생각한적이 많았던것 같다. 근데 서버 개발자가 프론트 개발자 한테 물어보는것 보다 프론트 개발자들은 이런이런식으로 데이터 리턴해줄수 있냐고 서버 개발자한테 더 많이 물어본다고 얘기들었을때는 조금 놀랐다. 그래서 이번에 공부하게 된 swagger라는 기능이 참 재미있었다. 뭔가 이걸 배우면서 "아! 이게 협업이구나" 싶기도 했었다. 아무튼 swagger에 대해 배워 이번기회에 공유 해보도록 하겠다.

swagger: swagger란 기능 명세서를 주 기능으로 삼는다. 서버에서 어떤 기능을 만들었을때 어떤 인자를 받아야 하고 어떤식으로 응답을 주며 성공시에는 어떤 코드 실패시에는 어떤 코드 등을 받을수있는지 에 대해 설명해주는 문서 라고 이해했다. swagger를 배우며 신기했던점은 단순 사용법을 알려주는 문서가 아닌 실제로 테스트를 해볼수 있던것에 대해 좀 wow 했다.

swagger 설정해보기

main.ts
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger';

declare const module: any;

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  const port = process.env.PORT || 3000;

  const config = new DocumentBuilder()
    .setTitle('nest practice')
    .setDescription('my nest practice')
    .setVersion('1.0')
    .addCookieAuth('connect.sid')
    .addTag('practice')
    .build();
  const document = SwaggerModule.createDocument(app, config);
  SwaggerModule.setup('api', app, document);

  await app.listen(port);

  if (module.hot) {
    module.hot.accept();
    module.hot.dispose(() => app.close());
  }
}
bootstrap();

swagger를 적용하기 위해서는 우선 @nestjs/swagger와 swagger-ui-express 패키지를 다운받아야한다. 이후 main.ts에서 설정을 해줘야한다.

swagger는 다양한 옵션이 있다. body,param,query등 옵션에 따라 다양한 swagger 옵션을 제공할수있다.

user.controller.ts

@ApiTags('USERS')
@Controller('users')
export class UserController {
  @Inject()
  private userService: UserService;

  @ApiOperation({ summary: '회원가입' })
  @Post()
  postUsers(@Body() data: JoinRequestDto) {
    this.userService.postUsers(data);
  }
}

ApiTags부터 설명하자면 기능을 묶는 역할이라고 보면 쉽다.

이런식으로 users기능 따로 dm기능 따로 묶어서 보여주는 카테고리화이다.

ApiOperation은 해당기능에 대한 설명을 붙일수가 있다. 보통 컨트롤러에 붙이는데 하나하나의 서비스가 아닌 서비스를 조합하여 어떤 기능을 만들고자 하였는가를 설명하는 역할을 하는 옵션이라고 보면된다.

ApiParam, ApiQuery, ApiBody등은 해당 파라미터값을 swagger에서도 사용가능하게 등록한다 => body값을 넣게 해주거나, param값, query값 등을 swagger에서 사용가능

@ApiTags('DM')
@Controller('api/workspaces/:url/dms')
export class DmsController {
  @ApiParam({
    name: 'url',
    description: '워크스페이스 url',
    required: true,
  })
  @ApiParam({
    name: 'id',
    description: '사용자 id',
    required: true,
  })
  @ApiQuery({
    name: 'perPage',
    required: true,
    description: '한번에 가져오는 갯수',
  })
  @ApiQuery({
    name: 'page',
    required: true,
    description: '불러올 페이지',
  })
  @Get(':id/chats')
  getChat(
    @Query() query,
    @Query('perPage') perPage: string,
    @Query('page') page: string,
    @Param() param,
    @Param('id') id: string,
    @Param('url') url: string,
  ) {
    console.log(query.perPage, query.page);
    console.log(param.url);
    console.log(param.id);
  }

@ApiProperty
객체로 값을 받거나 리턴할때 객체안 property에 부여하여 각 property값을 swagger에서도 request값으로 보내거나 response값으로 받을수있다.

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

export class JoinRequestDto {
  @ApiProperty({
    example: 'abc@gmail.com',
    description: '이메일',
    required: true,
  })
  public email: string;

  @ApiProperty({
    example: 'applemonster',
    description: '닉네임',
    required: true,
  })
  public nickname: string;

  @ApiProperty({ example: '1q2w3e4r', description: '비밀번호', required: true })
  public password: string;
}

response dto는 swagger를 안만들꺼면 안만들어도 되는데 만약 swagger를 만들생각이라면 response dto도 만들어서 어떻게 값이 return되야 하는지 front-end 개발자에게 알려줘야한다.

user.controller.ts
  @ApiResponse({ type: UserDto, description:'성공', status: 200 })
  @ApiOperation({ summary: '내 정보 조회' })
  @Get()
  getUsers() {}

  @ApiResponse({ type: UserDto, description:'성공', status: 200 })
  @ApiOperation({ summary: '로그인' })
  @Post('login')
  logIn() {}

response가 중요한 method는 보통 get method일것이다. 이때 response타입을 전달해주려면 @ApiResponse를 달고 안에 config 옵션에 type:만들어둔 response dto를 전달해주고 status로 하여금 성공했을때 어떤 status를 리턴받을수있는지도 정해줄수있다.

배우면서 재미는 있었지만 하나하나 api마다 모두 기능을 달아줄걸 생각하니 조금은 품이 드는 작업이겠구나 싶기도 하지만 내가 드는 품으로 좀더 빠른 개발 프로세스를 갖출수있다면 응당해야하는 일이기에 앞으로는 조금 열심히 달아볼 생각이다.

profile
왜? 라는 질문을 중요시하는 서버 개발자입니다

0개의 댓글