ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [nest.js] swagger 적용하기
    TIL 2024. 5. 29. 16:04

     

     

    왜 swagger를 쓰는가?)

     

    swagger 를 사용하면 api명세서를 코드내에서 자동으로 쓸 수 있게해준다

     

    api가 많아질경우 api명세서를 쓰는 시간을 훨씬 더 단축시킬 수 있고,

     

    백엔드 작업을 하다보면 놓친부분이나, api명세서 변경이 꽤 많이 일어난다.

     

     

    그럴때마다 코드와 api명세서를 둘다 수정하는 것은 시간도 오래걸리고, 만약 코드만 수정하고, api명세서 수정하는 것을 깜빡하면

     

    프론트엔드쪽에서는 잘못된 명세서를 많은 시간을 낭비하게된다.  

     

     

     

     

     

     

    swagger 설치하기

     

    npm install --save @nestjs/swagger

     

     

     

     

    main.ts에 swagger 적용하기)

     

    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('nest-practice-youtube')             // 명세서 제목
        .setDescription('nest practice description')   // 명세서 설명
        .setVersion('1.0')                             // 명세서 버전
        .addTag('cats')                                // 명세서 태그 
        .build();                                      // 명세서 생성(필수)
      const document = SwaggerModule.createDocument(app, config);
      SwaggerModule.setup('api', app, document);
    
      await app.listen(3000);
    }
    bootstrap();

    https://docs.nestjs.com/openapi/introduction

     

     

    ㄴ 별도의 파일에 swagger config를 작성해준뒤 main.ts에서 불러올 수도있다.

     

     

     

     

     

     

     

     

    api에 swagger 적용하기)

     

    @ApiTags('channel')
    @Controller('channel')
    export class ChannelController {
      constructor(private channelService: ChannelService) {}
    
      //회원가입
      @Post()
      @ApiOperation({ summary: '회원가입' })
      @ApiCreatedResponse({ description: 'created id' })
      @ApiConflictResponse({ description: 'id duplicate' })
      async signUp(
        @Body(ValidationPipe) signUpDto: SignUpDto,
      ): Promise<ChannelEntity> {
        return await this.channelService.signUp(signUpDto);
      }
      
       //채널상세보기
      @Get(':channelIdx')
      @ApiOperation({ summary: 'get channel in detail' })
      @ApiParam({ name: 'channelIdx' })
      @ApiBadRequestResponse({ description: 'no channelIdx' })
      @ApiNotFoundResponse({ description: 'not found channel' })
      @ApiOkResponse({ description: 'ok' })
      @UseGuards(AuthGuard)
      async getChannelInfo(
        @GetUser() loginUser: LoginUser,
        @Param('channelIdx', ParseIntPipe) channelIdx: number,
      ): Promise<{
        channel: ChannelEntity;
        subscribe: boolean;
      }> {
        const subscribeState = await this.channelService.getSubscrbeState(
          loginUser.idx,
          channelIdx,
        );
        const channel = await this.channelService.getChannelByIdx(channelIdx);
    
        return {
          channel,
          subscribe: subscribeState,
        };
      }

     

     

     

     

    @ApiTags 

    ㄴ api들을 태그별로 분류한다

    ㄴ컨트롤러에 쓸 수도 있고, 개별api에 쓸 수도 있다

     

     

     

     

    @ApiOperation

    ㄴapi 설명

     

     

     

     

    @ApiResponse

    ㄴ 각각의 상태코드 기본값 예외처리로도 쓸 수 있음 (ex) @ApiCreatedResponse,  @ApiConflictResponse ... )

    ㄴ 상태코드, 설명등을 추가할수 있음

     

     

     

     

    @ApiBody

    @ApiParam

    @ApiQuery

     

    ㄴ 필요한 body, param, query 지정

    ㄴ변수명, 타입지정(dto, string)

     

     

     // SignupDto
     
     export class SignUpDto {
      @IsString()
      @Length(1, 20)
      @ApiProperty({
        example: 'testid',
        description: '1-20자',
      })
      id: string;
    
      @IsString()
      @Length(8, 20)
      @IsStrongPassword({
        minLength: 8,
      })
      @ApiProperty({
        example: 'testpw',
        description: '8-20자',
      })
      pw: string;
    
      @IsString()
      @Length(1, 10)
      @ApiProperty({
        example: 'testname',
        description: '1-10자',
      })
      name: string;
    }
      
      
      
      
      //컨트롤러
      
      //회원가입api
      @Post()
      @ApiOperation({ summary: '회원가입' })
      @ApiBody({ type: SignUpDto })
      @ApiCreatedResponse({ description: 'created id' })
      @ApiConflictResponse({ description: 'id duplicate' })
      async signUp(
        @Body(ValidationPipe) signUpDto: SignUpDto,
      ): Promise<ChannelEntity> {
        return await this.channelService.signUp(signUpDto);
      }

     

     

     

     

     

     

     

     

Designed by Tistory.