그 전까지 DB 스키마 구성, nest 기본 설정 등을 마쳤다.

오늘부터 API 구현을 시작했다.

Swagger란?

swagger는 내가 개발한 REST API를 편리하게 문서화 해주는고, 이를 통해 제 3자가 관리 및 직접 사용해 볼 수 있게 해주는 프레임워크이다. API를 생성할 때 몇 가지 설정을 해주면 해당 정보를 직관적으로 적어줄 수 있어 협업을 할 때 굉장히 편리해보인다. 우리는 프론트엔드와 협업을 하기 위해 swagger를 이용하게 되었다.

Swagger 설정

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

export class BaseAPIDocument {
  public builder = new DocumentBuilder();

  public initializeOptions() {
    return this.builder
      .setTitle('HY-FES API DOCS')
      .setDescription(
        `이 문서는 한양대학교 정보통신관에서 최초로 시작되어 
				일년에 한바퀴를 돌면서 받는 사람에게 행운을 주었고 
				지금은 당신에게로 옮겨진 이 편지는 4일 안에 당신 곁을 떠나야 합니다. 
				이 문서를 포함해서 7통을 행운이 필요한 사람에게 보내 주셔야 합니다. 
				공유해도 좋습니다. 혹 미신이라 하실지 모르지만 사실입니다.`,
      )
      .setVersion('1.0.0')
      .addTag('swagger')
      .build();
  }
}

우선 swagger를 사용하기 위해서 기본설정을 해주었다. swagger는 nestJS에서 사용할 수 있게 모듈이 제공되어 있으므로 swagger를 npm으로 설치해주고 config 파일안에 위에 있는 코드를 작성해주었다.

BaseAPIDocument라는 객체를 생성해주고 멤버 변수로 builder를 설정해준다. 해당 builder를 DocumentBuilder 함수를 통해서 swagger 페이지의 기본 설정을 저장할 수 있다.

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

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

  app.useGlobalPipes(new ValidationPipe());

  await app.listen(3000);
}
bootstrap();

이제 기본 설정을 가지고 있는 객체를 호출해서 페이지를 만들고 보내주면 된다. config와 document는 찾아보니 config파일 안에 설정 할 때 같이 해줘도 문제가 없을 듯 하다. 하지만 app을 인수로 가지기 때문에 조금 더 편리하게 구현하기 위해서 main.ts에 넣었다.

config 변수에는 우리가 기본 설정을 할 수 있게 만들었던 객체를 이용하여 기본 설정을 저장해주고, 해당 정보를 토대로 document 변수에 SwaggerModule에 있는 createDocument 메소드를 이용해 페이지를 구성해준다. 마지막으로 setup 메소드를 호출하여 api 엔드포인트에 document를 보내주면 끝이다.


팀원들과 함께 구성해 본 첫 API

@ApiTags('festival controller')
@Controller('festival')
export class FestivalController {
  constructor(private readonly festivalService: FestivalService) {}

  @ApiOperation({
    summary: '축제 위치 불러오기 API',
    description: '축제 위치 불러오기 API',
  })
  @ApiResponse({
    status: 404,
    description: '해당 학교 코드 없음',
  })
  @ApiOkResponse({
    description: '성공',
    type: Position,
  })
  @ApiParam({
    name: 'code',
    description: '학교 코드',
  })
  @Get('/position')
  async getFestivalPosition(@Query('code') code: string): Promise<Position> {
    return await this.festivalService.getFestivalPosition(code);
  }

우선 우리가 설정한 swagger를 우리가 만들 API에 적용하는 방법을 알아보았다. 여러가지 데코레이터들을 이용하면 많은 정보를 표현할 수 있는데, 우리가 이용한 정보는 5가지가 있다.

@ApiTags 를 이용하면 swagger에 모듈 단위로 API를 모을 수 있게 해준다.

@ApiOperation을 이용하면 API에 대한 설명을 작성할 수 있다.

@ApiResponse를 이용하면 오류가 나거나 했을 때 어떤 오류 상태를 알려줄지 정할 수 있다.

@ApiOkResponse를 이용하면 성공적인 API 호출에 대한 응답을 정의할 수 있다.

@ApiParam을 이용하면 우리가 인자로 받을 데이터에 대한 정보를 정의할 수 있다.