코딩/Nest.js

Swagger

춘 몽 2024. 4. 24. 06:46

- Swagger란 간단히 말해 RestAPI에 대한 설명과 테스트를 해볼 수 있는 사이트를 만드는 것이다.

 

- 설치

yarn add @nestjs/swagger

 

 

- 세팅

main.ts에 swagger에 대한 코드를 작성해야하는데 그러면 main.ts가 지저분해지므로

setupSwagger.ts 라는 파일을 만들고 안에

import { INestApplication } from '@nestjs/common';
import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger';

export function setupSwagger(app: INestApplication): void {
  const config = new DocumentBuilder()
    .setTitle('Farmfarm')
    .setDescription('팜팜 API 입니다.')
    .setVersion('1.0')
    // .addTag('Farmfarm')
    .build();
  const document = SwaggerModule.createDocument(app, config);
  SwaggerModule.setup('api', app, document); // 'api' 대신에 다른거 적으면 그 주소로 가짐
}

이렇게 작성 후, main.ts에는

  setupSwagger(app);

를 추가해 준다.

 

- 접속

nest주소 뒤에 /api를 붙인 주소로 가면 Swagger를 볼 수 있다

(위 경우는 listen(3333) 이므로 localhost:3333/api 로 가면 된다.)

 

- Controller

controller로 가서 @Controller()밑에 @ApiTags()로 내용을 적는다

@Controller('auth')
@ApiTags('회원 API')
export class AuthController {
  constructor(private readonly authService: AuthService) {}

그럼 이렇게 컨트롤러 별로 작성한 태그가 표시된다.

 

그리고 @Post와 @Get 상관없이

@ApiOperarion({}) 으로 각 api에 대한 설명을 적는다

@ApiResponse({}) 로 각 api의 응답에 대한 설명을 적는다

Post의 경우 @Body로 Get의 경우 @Query로 받는 데이터를 정의하는데 이때 dto 처리를 해주었다면 @ApiBody로 받는 데이터에 대한 처리는 안해줘도 되는것 같다.

그리고 맨 밑에 첨부해두었는데, @ApiResponse 말고 각 상태코드에 따른 응답들이 있다. 하지만 ApiResponse로 통일한 이유는 일단 코드가 깔금해지기 때문이다. 해당 응답들은 대부분 코드명이 길다보니 한줄에 처리가 안되서 지저분해본인다.

또한, 내가 아직 프론트담당자분과 일을 해보지 않아서 정확하진 않지만, 프론트에서 해당 코드의 번호(status)에 따른 처리를 하고 있으시다면 나도 정확히 몇번의 상태코드를 보내는지 명확히 표시해주는게 좋아보인다고 생각했다.

// Post 예시
@Post('join')
  @ApiOperation({ summary: '회원가입 & 정보수정' })
  @ApiResponse({ status: 201, description: 'User 테이블 반환', type: User })
  @ApiResponse({ status: 400, description: '빈칸 존재', type: Error })
  @ApiResponse({ status: 500, description: '회원 가입 실패(DB)', type: Error })
  createUser(@Body() createUserInput: CreateUserInput): Promise<User> {
    return this.authService.create({ createUserInput });
  }
// Get 예시
@Get('farm')
  @ApiOperation({ summary: '텃밭들 검색' })
  @ApiResponse({ status: 200, description: '텃밭들 검색 결과', type: [Farm] })
  getFarms(@Query() getFarmsInput: GetFarmsInput): Promise<Farm[]> {
    return this.farmService.getFarms({ getFarmsInput });
  }

 

밑에 설정이 나올거지만, @ApiResponse의 type을 보면 Class를 그대로 넣은부분이 있다.

이 경우는 TypeORM을 통해 반환된 Entity(테이블)을 그대로 return하기 때문에 해당 Class를 그대로 타입에 넣었으며, 아래에 나오는 설정을 해놓으면 자동으로 해당 내용들이 Swagger의 Response부분에 표시된다.

무튼 이렇게 작성했다면 Swagger에서 이런식으로 표시된다.

 

- Entity, dto

dto에 적은 내용이 Swagger의 Example Value에 표시된다.

Entity는 앞서 말했듯이 type을 Entity Class로 하게되면 해당 entity에 작성한 그대로가 Swagger의 Response에 표시된다.

또한 dto에서 PickType등을 사용하여 Entity를 가져다 dto에 사용했다면 역시나 해당 Entity에 적어놓은 부분이 Swagger의 Example Value에 표시된다.

 

때문에 우선 Entity를 먼저 작업해주는게 좋다.

Entity에는 간단하게 컬럼들에 @ApiProperty()를 추가해주면 된다.

import { ApiProperty } from '@nestjs/swagger';
import { IsNotEmpty, IsString, MaxLength } from 'class-validator';
import { User } from 'src/apis/02.Users/entities/users.entity';
import { Column, Entity, JoinColumn, OneToOne, PrimaryColumn } from 'typeorm';

@Entity()
export class Auth {
  @ApiProperty({ maxLength: 20, example: 'TomatoKing' })
  @PrimaryColumn({ length: 20 })
  @IsNotEmpty({ message: '아이디를 입력하세요' })
  @IsString({ message: '아이디는 string 타입이어야 합니다' })
  @MaxLength(20, { message: '아이디는 최대 20까지 입력할 수 있습니다' })
  user_id: string;

  @Column({ length: 60 })
  @IsNotEmpty({ message: '비밀번호를 입력하세요' })
  @IsString({ message: '비밀번호는 string 타입이어야 합니다' })
  user_pw: string;

  @ApiProperty({ description: 'User 테이블 id와 결합' })
  @JoinColumn()
  @OneToOne(() => User)
  user: User;
}

비밀번호에 관련된 내용은 노출되면 안되므로 제외해주었습니다.

@Entity()
export class User {
  @ApiProperty({
    description: 'uid',
    maxLength: 36,
    example: '49b3bd13-0a49-4f97-9b79-733bb0a709da',
  })
  @PrimaryGeneratedColumn('uuid')
  @IsNotEmpty()
  id: string;

  @ApiProperty({ uniqueItems: true, maxLength: 50, example: 'Mintchoco@gmail.com' })
  @Column({ unique: true, length: 50 })
  @IsNotEmpty()
  user_email: string;

  @ApiProperty({
    required: false,
    example: '전라남도 순천시 해룡면 신대리 중흥X단지 XXX동 XXX호',
  })
  @Column()
  user_address: string;

  @ApiProperty({ default: 0 })
  @Column({ type: 'tinyint', default: 0 })
  user_type: number;

  @ApiProperty()
  @CreateDateColumn()
  createdAt: Date;
}

위처럼 유니크키, 디폴트값을 표시해주면 Schema에서 해당 내용을 확인 할 수 있으며, required를 false로 해주면 없어도 되는 값이라는 의미로 Schema에서 빨간색 별표가 사라집니다.

 

 

 

 

 

 

 

 

 

 

 

  • @ApiOkResponse(): 200 OK 응답에 대한 설명을 제공합니다.
  • @ApiCreatedResponse(): 201 Created 응답에 대한 설명을 제공합니다.
  • @ApiAcceptedResponse(): 202 Accepted 응답에 대한 설명을 제공합니다.
  • @ApiNoContentResponse(): 204 No Content 응답에 대한 설명을 제공합니다.
  • @ApiMovedPermanentlyResponse(): 301 Moved Permanently 응답에 대한 설명을 제공합니다.
  • @ApiBadRequestResponse(): 400 Bad Request 응답에 대한 설명을 제공합니다.
  • @ApiUnauthorizedResponse(): 401 Unauthorized 응답에 대한 설명을 제공합니다.
  • @ApiNotFoundResponse(): 404 Not Found 응답에 대한 설명을 제공합니다.
  • @ApiForbiddenResponse(): 403 Forbidden 응답에 대한 설명을 제공합니다.
  • @ApiMethodNotAllowedResponse(): 405 Method Not Allowed 응답에 대한 설명을 제공합니다.
  • @ApiNotAcceptableResponse(): 406 Not Acceptable 응답에 대한 설명을 제공합니다.
  • @ApiRequestTimeoutResponse(): 408 Request Timeout 응답에 대한 설명을 제공합니다.
  • @ApiConflictResponse(): 409 Conflict 응답에 대한 설명을 제공합니다.
  • @ApiTooManyRequestsResponse(): 429 Too Many Requests 응답에 대한 설명을 제공합니다.
  • @ApiGoneResponse(): 410 Gone 응답에 대한 설명을 제공합니다.
  • @ApiPayloadTooLargeResponse(): 413 Payload Too Large 응답에 대한 설명을 제공합니다.
  • @ApiUnsupportedMediaTypeResponse(): 415 Unsupported Media Type 응답에 대한 설명을 제공합니다.
  • @ApiUnprocessableEntityResponse(): 422 Unprocessable Entity 응답에 대한 설명을 제공합니다.
  • @ApiInternalServerErrorResponse(): 500 Internal Server Error 응답에 대한 설명을 제공합니다.
  • @ApiNotImplementedResponse(): 501 Not Implemented 응답에 대한 설명을 제공합니다.
  • @ApiBadGatewayResponse(): 502 Bad Gateway 응답에 대한 설명을 제공합니다.
  • @ApiServiceUnavailableResponse(): 503 Service Unavailable 응답에 대한 설명을 제공합니다.
  • @ApiGatewayTimeoutResponse(): 504 Gateway Timeout 응답에 대한 설명을 제공합니다.
  • @ApiDefaultResponse(): 기본적인 응답에 대한 설명을 제공합니다. (사용되지 않는 응답 코드에 대한 설정)

'코딩 > Nest.js' 카테고리의 다른 글

GlobalFilters  (0) 2024.04.22
Global Pipes  (0) 2024.04.22
환경변수 ConfigModule  (0) 2024.04.22
오류 상태 코드  (0) 2024.04.20
Multer  (0) 2024.04.18