Swagger는 API 문서 자동화 도구이다.
경험이 부족해 기존에 작성해 둔 api문서를 매번 수정해야 하는 일과
문서와 코드를 동일하게 작성해야 하는데 실수하는 경우가 있기 때문에
코드와 자동으로 동기화되어 작성된다는 것은 큰 메리트가 있다.
또한 api 문서를 웹에 공유할 수 있어 최신화와 공유측면에서
아주 훌륭하고, 웹 자체에서 테스트도 가능하다
npm install --save @nestjs/swagger swagger-ui-express
NestJS v9 부터는 @nest/swagger 패키지를 사용할 때 swagger-ui-express 패키지는 더 이상 필요하지 않다고 한다.
// main.ts
async function bootstrap() {
// app옵션클래스
const appOption = new AppOptions();
const app = await NestFactory.create<NestApplication>(
AppModule,
appOption.getNestOptions(),
);
// swagger 등록
const apiDocument = SwaggerModule.createDocument(
app,
appOption.initializeSwaggerDoc(),
);
SwaggerModule.setup('api/v1/docs', app, apiDocument);
...
// appOption.ts
export class AppOptions {
private readonly doc: DocumentBuilder = new DocumentBuilder();
public initializeSwaggerDoc() {
return this.doc
.setTitle('Study-meet API') // 문서 제목
.setDescription('study meet API개발 문서') // 문서 설명
.setVersion('1.0') // 문서 버전
.addBearerAuth(
{
type: 'http',
scheme: 'bearer',
name: 'JWT',
in: 'header',
},
'access-token',
)
.addCookieAuth('refreshToken')
.setContact('seungjun', '', 'cjstkrak@gmail.com')
.build();
}
...
// 특정 게시물 조회 api
@ApiOperation({
summary: '특정 게시물 조회',
description: '특정 게시물 조회',
})// api 제목같은 역할
@ApiParam({ name: 'id', description: '게시물 id로 검색', example: 5 })
// parameter에 대해서 설명
@ApiResponse({
status: 200,
description: '게시물 조회',
})
// response 유형, 이 외에도 실패의 경우를 전부 작성해야한다.
@HttpCode(200)
@Get('/:id')
async getBoard(@Param('id') id: string) {
return await this.boardService.getBoard(+id);
}
이 외에도 dto에서도 @ApiProperty()
를 사용하여 각 요소들에 대해 작성해 주어야 한다.
이런식으로 request, response 설명 등이 들어간 문서가 작성된다
Response를 일일이 적어줘야해서 코드가 길어지고,
그로인해 가독성이 떨어지게 된다.
알아본 해결방법으로는 두가지가 존재한다.
//nest-cli.js
"compilerOptions": {
"deleteOutDir": true,
"plugins": [
{
"name": "@nestjs/swagger",
"options": {
"classValidatorShim": true,
"introspectComments": true,
"controllerKeyOfComment": "summary"
}
}
]
}
옵션 | 기본 | 설명 |
---|---|---|
dtoFileNameSuffix | ['.dto.ts', '.entity.ts'] | DTO(Data Transfer Object) 파일 접미사 |
controllerFileNameSuffix | .controller.ts | 컨트롤러 파일 접미사 |
classValidatorShim | true | true로 설정하면 모듈은 class-validator유효성 검사 데코레이터를 재사용합니다(예: 스키마 정의에 @Max(10)추가 ).max: 10 |
dtoKeyOfComment | 'description' | 주석 텍스트를 on 으로 설정하는 속성 키입니다 ApiProperty. |
controllerKeyOfComment | 'description' | 주석 텍스트를 on 으로 설정하는 속성 키입니다 ApiOperation. |
introspectComments | false | true로 설정하면 플러그인은 주석을 기반으로 속성에 대한 설명과 예제 값을 생성합니다. |
@ApiOperation({
summary: '회원가입',
})
->
/**
* 회원가입 API
*/
으로 대체할 수 있고, 주석으로 처리되어 가독성이 향상된다.
하지만 단점으로는 기능이 많이 부족하다
description까지 작성하려면 어차피 @ApiOperation을 써야한다.
dto나 간단한 api에서는 효과적이나 가독성이 드라마틱하게 향상되지는 않고,
부족한 정보, 기능들이 아쉬웠다.
출처: https://devnm.tistory.com/29#4.%20%EC%A0%81%EC%9A%A9%ED%95%98%EA%B8%B0-1
내가 생각한 정답에 가까운 방법인 것 같다.
스웨거문서를 custom 하여 다른 데코레이터로 만들어두고 사용하는 방법이
재사용성이나 가독성 측면에 있어서 옳은 것 같다.
swagger의 구조에 대해서 더 공부하고 적용해보도록하자
https://jhyeok.com/nestjs-swagger/ Swagger
https://docs.nestjs.com/openapi/introduction Swagger
https://wooserk.tistory.com/105 Swagger Plugin