Nest.js를 global로 설치한 후, nest 명령어를 이용하여 swagger를 적용해볼 Nest.js 프로젝트를 생성한다.
# Nest.js 설치
$> npm i -g @nestjs/cli
# Nest.js 프로젝트 생성
$> nest new swagger-study
Nest.js 프로젝트를 생성 완료를 했으면 swagger를 사용하기 위해 dependency를 설치해준다.
$> npm install --save @nestjs/swagger swagger-ui-express
# fastify를 사용하는 경우 swagger-ui 대신 fastify-swagger로 설치
$> npm install --save @nestjs/swagger fastify-swagger
Swagger를 사용하기 위해서 main.ts 파일에 swagger document를 작성한다.
main.ts 👇
import { NestFactory } from '@nestjs/core';
import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger';
import { AppModule } from './app.module';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
const config = new DocumentBuilder()
.setTitle('Swagger Example')
.setDescription('Swagger study API description')
.setVersion('1.0.0')
.addTag('swagger')
.build();
// config를 바탕으로 swagger document 생성
const document = SwaggerModule.createDocument(app, config);
// Swagger UI에 대한 path를 연결함
// .setup('swagger ui endpoint', app, swagger_document)
SwaggerModule.setup('api', app, document);
await app.listen(3000);
}
bootstrap();
Swagger에 대한 document를 작성한 후에는 SwaggerModule의 .setup() 을 호출하여 Swagger UI의 path를 연결해준다.
위와 같은 값으로 설정한 후 로컬로 띄운다면, http://localhost:3000/api
로 접속하였을 때 Swagger UI를 확인할 수 있다.
Swagger document를 바로 main.ts에 작성하지 않고, 별도의 document로 작성한 뒤 main.ts에 mount 하는 방식으로 진행할 수도 있다.
swagger.documnet.ts 👇
import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger';
export class BaseAPIDocument {
public builder = new DocumentBuilder();
public initializeOptions() {
return this.builder
.setTitle('Swagger Example')
.setDescription('Swagger study API description')
.setVersion('1.0.0')
.addTag('swagger')
.build();
}
}
main.ts 👇
import { NestFactory } from '@nestjs/core';
import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger';
import { AppModule } from './app.module';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
const config = new BaseAPIDocumentation().initializeOptions();
const document = SwaggerModule.createDocument(app, config);
SwaggerModule.setup('api', app, document);
await app.listen(3000);
}
bootstrap();
Swagger document에 대한 기본 설정을 마친 후 npm run start
를 통해 프로젝트를 실행시킨후 Swagger UI endpoint로 들어가면 다음과 같이 작성한 document에 맞는 값으로 설정된 swagger를 확인할 수 있다.
swagger에서는 다양한 decorator를 제공해서 swagger document에 쉽게 api에 대한 설명을 추가할 수 있다.
API에서 주고 받을 모델에 대한 명세를 @ApiProperty annotation을 통해 swagger document에 작성할 수 있다.
example property를 통해 모델의 property에 대한 예시값을, property에 대한 설명을 description property를 통해 swagger document에서 보여줄 수 있다.
import { ApiProperty } from '@nestjs/swagger';
export class CreateSwaggerDto {
@ApiProperty({
example: 'swagger',
description: 'this is name of swagger study',
})
name: string;
@ApiProperty({
example: 'swagger detail',
description: 'this is detail of swagger study',
})
detail: string;
}
import { Controller, Get, Post } from '@nestjs/common';
import { ApiTags } from '@nestjs/swagger';
@ApiTags('Swagger') // swagger에 tag를 생성해줌
@Controller('swagger')
export class SwaggerController {
@ApiOperation({ summary: 'swagger get endpoint'}) // api 설명
@Get()
getSwagger() {
return 'this is get swagger page';
}
@Post()
postSwagger() {
return 'this is post swagger paoge';
}
}
import { Controller, Get, Post } from '@nestjs/common';
import { ApiOperation , ApiTags } from '@nestjs/swagger';
@ApiTags('Swagger') // swagger에 tag를 생성해줌
@Controller('swagger')
export class SwaggerController {
@ApiOperation({ summary: 'swagger get endpoint'}) // api 설명
@Get()
getSwagger() {
return 'this is get swagger page';
}
@ApiOperation({ summary: 'swagger post endpoint' })
@Post()
postSwagger() {
return 'this is post swagger paoge';
}
}
import { Controller, Get, Post } from '@nestjs/common';
import { ApiOperation, ApiResponse, ApiTags } from '@nestjs/swagger';
@ApiTags('Swagger')
@Controller('swagger')
export class SwaggerController {
@ApiOperation({ summary: 'swagger get endpoint' })
// response 값에 대한 예시 표시
@ApiResponse({
status: 403,
description: 'Forbidden',
})
@Get()
getSwagger() {
return 'this is get swagger page';
}
@ApiOperation({ summary: 'swagger post endpoint' })
@Post()
postSwagger() {
return 'this is post swagger page';
}
}
@ApiResponse를 사용할 때 schema property를 이용한다면 response로 반환하는 값에 대한 명세를 swagger document에 표시할 수 있다.
@ApiResponse로 사용할 경우에는 status를 지정해서 작성해줘야 하지만 swagger에서 각 status에 따른 api response annotation을 별도로 제공하기 때문에 status에 맞는 annotation 사용을 통해서도 response 예시를 표시할 수 있다.
📁 제공하는 다양한 status별 annotation들
import { Controller, Get, Post } from '@nestjs/common';
import { ApiBody, ApiConsumes, ApiOkResponse, ApiOperation, ApiResponse, ApiTags } from '@nestjs/swagger';
@ApiTags('Swagger')
@Controller('swagger')
export class SwaggerController {
@ApiOperation({ summary: 'swagger get endpoint' })
// response 값에 대한 예시 표시
@ApiResponse({
status: 403,
description: 'Forbidden',
})
// status 200에 대한 response 표시를 제공
@ApiOkResponse({
description: 'Success',
})
@Get()
getSwagger() {
return 'this is get swagger page';
}
@ApiOperation({ summary: 'swagger post endpoint' })
@Post()
postSwagger() {
return 'this is post swagger page';
}
}
import { Body, Controller, Get, Post } from '@nestjs/common';
import {
ApiOperation,
ApiParam,
ApiTags,
} from '@nestjs/swagger';
import { CreateSwaggerDto } from './dto/CreateSwaggerDto.dto';
@ApiTags('Swagger')
@Controller('swagger')
export class SwaggerController {
@ApiOperation({ summary: 'swagger get endpoint' })
@ApiQuery({
name: 'name',
enum: ['enum1', 'enum2'],
})
@Get()
getSwagger() {
return 'this is get swagger page';
}
}
import { Controller, Get, Post } from '@nestjs/common';
import { ApiOperation, ApiResponse, ApiTags } from '@nestjs/swagger';
@ApiTags('Swagger')
@Controller('swagger')
export class SwaggerController {
@ApiTags('Swagger')
@Controller('swagger')
export class SwaggerController {
@ApiOperation({ summary: 'swagger get endpoint' })
@ApiParam({
name: 'swagger param',
type: 'string',
})
@Get()
getSwagger() {
return 'this is get swagger page';
}
}
import { Controller, Get, Post } from '@nestjs/common';
import { ApiOperation, ApiResponse, ApiTags } from '@nestjs/swagger';
@ApiTags('Swagger')
@Controller('swagger')
export class SwaggerController {
@ApiOperation({ summary: 'swagger post endpoint' })
@ApiConsumes('multipart/form-data') // Body를 받을 때의 mime type 설정
// Body에 대한 명세 설정
@ApiBody({
description: 'post swagger',
type: CreateSwaggerDto,
})
@Post()
postSwagger(@Body createSwaggerDto: CreateSwaggerDto) {
return 'this is post swagger page';
}
}
위와 같은 decorator 외에도 다양한 decorator를 사용할 수 있으며, 원하는 기능의 decorator를 커스텀하여 사용할 수도 있다.