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를 커스텀하여 사용할 수도 있다.