이번 한이음 프로젝트에서 Swagger를 사용하기 때문에 공부해 보겠다.
Swagger UI를 사용하면 개발 팀이든 엔드 유저든 누구나 구현 로직 없이도 API 리소스를 시각화하고 상호 작용할 수 있도록 도와줍니다. Swagger는 OpenAPI (이전 Swagger) 사양으로 자동 생성되며 시각적 문서를 통해 백엔드 구현 및 클라이언트 측 사용을 쉽게 할 수 있게 합니다. (Swagger 홈페이지의 설명)
우선 Nest.js가 있다는 가정하에 Swagger를 설치해준다
$ npm install --save @nestjs/swagger swagger-ui-express
main.ts 설정
import { NestFactory } from '@nestjs/core';
import { SwaggerModule, DocumentBuilder } from '@nestjs/swagger';
import { AppModule } from './app.module';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
const config = new DocumentBuilder()
.setTitle('Swagger-tutorial')
.setDescription('user API description')
.setVersion('1.0')
.build();
const document = SwaggerModule.createDocument(app, config);
SwaggerModule.setup('swagger', app, document);
await app.listen(3000);
}
bootstrap();
npm run start:dev로 실행시키고
$ npm run start:dev
localhost:3000/swagger/
로 접속하면
정상적으로 출력되는걸 볼 수 있다.
임의로 user라는 resource를 만들어주었다.
$ nest g res user
create-user.dto.ts 설정
export class CreateUserDto {
name : string;
age : number;
}
user.controller.ts 수정
import { Controller, Response, Get, Post, Body, Patch, Param, Delete, Res, HttpStatus } from '@nestjs/common';
import { UserService } from './user.service';
import { CreateUserDto } from './dto/create-user.dto';
import { UpdateUserDto } from './dto/update-user.dto';
import { ApiCreatedResponse, ApiOperation, ApiTags } from '@nestjs/swagger';
import { User } from './entities/user.entity';
@Controller('user')
@ApiTags('유저 API')
export class UserController {
constructor(private readonly userService: UserService) {}
@Post()
@ApiOperation({summary : '유저를 생성하는 API', description: '유저를 생성한다.' })
@ApiCreatedResponse({description: '유저를 생성한다', type: User})
async create(@Body() createUserDto: CreateUserDto) {
const user: User = await this.userService.createUser(createUserDto);
return user;
}
}
user.service.ts 수정
import { Injectable } from '@nestjs/common';
import { CreateUserDto } from './dto/create-user.dto';
import { UpdateUserDto } from './dto/update-user.dto';
@Injectable()
export class UserService {
createUser(createUserDto: CreateUserDto) {
return {
name : 'Kimjaehan',
age : 24
};
}
}
실행시키면
여기서 try it out을 누르고 아무것도 없이 excute해주면
user.service.ts에서 설정해준 값으로 잘 넘어오는 것을 확인 할 수 있다.
class-validator와 class-transformer를 설치한다.
$ npm i class-validator class-transformer
dto 파일에 타입과 swagger 데코레이터를 추가해준다.
create-user.dto
import {IsString, IsNumber} from 'class-validator'
import { ApiProperty } from '@nestjs/swagger';
export class CreateUserDto {
@ApiProperty({ description: '이름' })
@IsString()
name : string;
@ApiProperty({ description: '나이' })
@IsNumber()
age : number;
}
main에 pipe 연결 해준다
main.ts
기존코드에 await 하기 전에 추가
app.useGlobalPipes(
new ValidationPipe({
whitelist : true,
forbidNonWhitelisted : true,
transform : true
})
)
service 부분에 내가 입력한 값을 반환하게 수정해준다
user.service.ts
import { Injectable } from '@nestjs/common';
import { CreateUserDto } from './dto/create-user.dto';
import { UpdateUserDto } from './dto/update-user.dto';
@Injectable()
export class UserService {
createUser(createUserDto: CreateUserDto) {
return createUserDto
}
}
설정후 실행 시키면 설정한대로 Schemas도 지정된 것을 확인 할 수 있고
{name : 0
age : 1}
로 excute하면 "name must be a string"으로 제대로 오류가 나는걸 볼 수 있다.