* 정보제공용 글이 아닌 개발 일지입니다! 비판 환영
1. 서론
원래는 Transaction을 먼저 하려고 했는데, Swagger는 금방 하니까 빠르게 하고 그 다음에 해야겠다.
API를 개발하다보면 클라이언트에게 어떤 API가 만들어졌고 뭘 쓰면 되고, Request, Response는 이렇게 오고, 상태코드는 무엇들이 있고 등등 일일이 말로 설명하기 매우 번거로워진다.
그러자니 Postman 등을 활용해서 API 문서를 직접 만들기에도 상당한 시간도 걸리고, 실수할 여지도 있고, 추후 API가 변경되면 이를 수정해줘야하는 불편함이 있다.
이러한 불편함을 한번에 해결해줄 수 있는 고마운 존재가 있는데, 바로 Swagger OpenAPI이다.
오늘도 역시 공식 도큐먼트의 힘을 빌린다.
Documentation | NestJS - A progressive Node.js framework
Nest is a framework for building efficient, scalable Node.js server-side applications. It uses progressive JavaScript, is built with TypeScript and combines elements of OOP (Object Oriented Progamming), FP (Functional Programming), and FRP (Functional Reac
docs.nestjs.com
2. 설치
자, 공식 도큐먼트를 따라 하단의 커맨드를 실행시켜 패키지를 다운받는다.
npm install --save @nestjs/swagger swagger-ui-express
나는 Nest.js에서 Express를 사용하고 있으므로 상기 커맨드를 통해 패키지를 설치하면 된다. Fastify는 다른 커맨드를 통해 설치하면 된다고 한다.
설치가 모두 완료되었으면, main.ts에 Swagger Config를 진행해주면 된다.
// main.ts
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { ResponseInterceptor } from './common/interceptor/response.interceptor';
import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger';
async function bootstrap() {
console.log(`Starting with ${process.env.NODE_ENV}`);
const app = await NestFactory.create(AppModule);
// Swagger Config
const config = new DocumentBuilder()
.setTitle('산악회 홈페이지 API')
.setVersion('1.0')
.setContact('정지현', '', 'dinb1242@naver.com')
.build();
const document = SwaggerModule.createDocument(app, config);
SwaggerModule.setup('docs', app, document);
app.setGlobalPrefix('api/v1');
await app.listen(3000);
}
bootstrap();
나는 DocumentBuilder 객체에 메소드 체이닝으로 제목과 버전, 연락처 등을 Set 해주었다. 더 다양한 Setter들이 있으니, 추후 더 살펴봐야겠다.
Builder 객체를 초기화한 이후에, SwaggerModule.createDocument()로 도큐먼트를 만들어주고, 최종적으로 Module에 등록해주면 된다.
이때, SwaggerModule.setup()의 첫 번째 인자는 Swagger 문서에 접근하기 위한 엔드포인트이다. 나의 경우는 docs라고 적어주었는데, 이 경우 http://localhost:3000/docs 로 접근하면 된다.
3. 사용
이제 Config가 되었으니, http://localhost:3000/docs로 접근해본다.
아주 잘 나온다. 그럼 이제 직접 Swagger를 적용해보자. 사용법은 다른 좋은 블로그들에 자세히 나와있었다. 나는 화면에서 보이는 default 라고 적혀있는 API를 "예제 API"로 수정해볼 것이다!
지난 시간에 만들었던 예제 컨트롤러 클래스의 상단에 @ApiTags()를 사용해준다. 인자로는 표시될 텍스트를 넣어준다.
기존에 default로 되어있던 API가 방금 지정한 예제 API로 변경됨을 확인하였다!
근데 한 가지 문제가 발생했다... 지난 번에 main.ts에서 Global Prefix를 /api/v1으로 지정해주었는데, Swagger에는 이 Prefix가 반영이 안 되어 있는 것 같다. 당연히 호출해보면,
404 에러가 발생한다. 이렇게 되는 이유를 찾았는데, 지난 시간에 지정해둔 Global Prefix를 Set 해주는 코드가 Swagger Config의 하단에 있었기 때문에 해당 Prefix가 전역적으로 적용되기 전에 Swagger 문서가 먼저 만들어진 것이다!
setGlobalPrefix() 메소드를 Config보다 위로 올려주었고, 결과는
이제 잘 나온다!
내친 김에 각 API에도 제목을 달아주자. 각 API에 태그를 달기 위해서는 컨트롤러 내 엔드포인트를 담당하는 함수에 @ApiOperation() 데코레이터를 지정해주면 된다. 해당 데코레이터에는 자주 사용하는 두 가지 옵션이 있는데, 하나는 summary이며, 다른 하나는 description이다. summary는 제목을, description은 설명을 나타낸다.
두 속성을 모두 적용해보자!
이렇게 설정해주면 된다.
Swagger에도 잘 반영됨을 확인했다.
그런데 몇 가지 걸리는게 있다. 일단 Request body에 아무런 정보가 없고, Status 값도 201이 나와있긴 하지만, 명확한 설명이 없다.
이건 생성 API가 받는 DTO에 @ApiProperty() 데코레이터를 적용해주면 된다. 역시나 다른 블로그에 더 자세히 나와있어서 열심히 참고했다.
// create-example.dto.ts
import { ApiProperty } from '@nestjs/swagger';
export class CreateExampleDto {
@ApiProperty({
title: '제목',
example: 'Example Title',
})
title: string;
@ApiProperty({
title: '내용',
example: 'Example Content',
})
content: string;
}
이렇게 각 필드에 데코레이터를 적용해주고 다시 Swagger를 확인해보면
이쁘게 잘 나온다. 나의 경우, 해당 데코레이터의 옵션으로 title과 example를 지정해두었는데, title 옵션의 경우는 Swagger의 Schema 탭을 클릭하면 해당 필드가 어떤 제목인지 의미를 파악할 수 있다. example은 말 그대로 예제 데이터를 박아넣을 수 있다.
그 다음은 Status 값인데, 이건 @ApiResponse() 데코레이터를 각 엔드포인트 함수에 지정해주면 된다.
이렇게 description과 status를 지정해두고 Swagger를 다시 확인해보자.
잘 나온다. 각 Status의 Response 예제는 @ApiResponse() 데코레이터의 schema 옵션의 example 키에서 Value로서 JSON 데이터를 넣어주거나, 혹은 @ApiResponse() 데코레이터 내의 type에 DTO를 지정해주면 된다.
'좌충우돌 산악회 홈페이지 만들기' 카테고리의 다른 글
[좌충우돌 산악회 홈페이지 만들기 #6] Nest.js Transaction 처리 (0) | 2022.04.19 |
---|---|
[좌충우돌 산악회 홈페이지 만들기 #4] Nest.js에서 Exception Filter 만들기 (0) | 2022.04.17 |
[좌충우돌 산악회 홈페이지 만들기 #3] 공통 Response를 만들어보자 (0) | 2022.04.17 |
[좌충우돌 산악회 홈페이지 만들기 #2] TypeORM을 활용한 DB 연동과 Cross-env 및 Dotenv 세팅, 예제 컨트롤러/서비스 개발! (0) | 2022.04.17 |
[좌충우돌 산악회 홈페이지 만들기 #1] 필요한 것들을 나열해보자 (0) | 2022.04.15 |