따라하면서 배우기 NestJs #3 - 게시글 플젝 Pipe, Validation Check, Exception(약간씩 변형하여 작성)

kkikki·2024년 9월 21일

Pipe

데이터 형 변환과 데이터 유효성 체크를 위해서 사용
메소드가 호출되기 직전에 파이프 삽입


data transformation

데이터를 원하는 형식으로 변환
ex) string to integer
url은 string임 처음에


@UsePipes

핸들러 레벨에서 @UsePipes 데코레이터를 이용해서 사용


ParameterPipe


###Global Pipes

애플리케이션 레벨에서 사용
ex) useGlobalPipes


built-in Pipes

  • nestJS에는 기본적으로 6개의 Pipe가 있음.

-- ValidationPipe
-- ParseIntPipe
-- ParseBoolPipe
-- ParseArrayPipe
-- ParseUUIDPipe
-- DefaultValuePipe


class-validator 패키지

class-validator 패키지
https://github.com/nestjs/class-validator
데이터 유효성 체크를 위한 패키지


$ npm install class-validator class-transformer --save


게시물 생성시 pipe를 이용하여 유효성 체크

DTO 코드 - CreateBoardDto

import { IsNotEmpty } from 'class-validator';
export class CreateBoardDto {
  @IsNotEmpty()
  title: string;
  description: string;
}
  • class-validator 패키지 import 추가
  • @IsNotEmpty를 통해서
    입력값이 비었는지 확인
    empty이면 error반환

Controller

@Post()
  @UsePipes(ValidationPipe)  // 추가 부분
  createBoard(@Body() createBoardDto: CreateBoardDto): Board {
    return this.boardsService.createBoard(createBoardDto);
  }
  • @UsePipes(ValidationPipe) 를 통해 validation을 체크

  • title과 description이 빈 값이면 400 error


예외처리 1

  • 게시물 id로 호출할때 게시글이 없을 경우

service 부분 처리

  //개별 게시글 조회
  getBoardById(id: string): Board {

    const found = this.boards.find((board) => board.id === id);

    if (!found) {
      throw new NotFoundException(`게시글을 찾을 수 없어요 id: ${id} `);
    }
    return found;
  }

테스트 결과

없는 게시글일 경우 404 메시지 출력~!


Exception2

  • 없는 게시글 지우려고 할때, 예외처리

Service 코드 수정

  deleteBoard(id: string): void {
    const found = this.getBoardById(id);
    this.boards = this.boards.filter((board) => board.id !== found.id);
  }

this.boards.filter를 실행하기 전에
getBoardById(id) 에서 예외처리가 되어있다~!

없는 id를 삭제 시도하면
404 페이지 발생~!


커스텀 파이프

  • 일단 만들어 보자

src/boards/pipes/board-status-validation.pipe.ts

  • boards 폴더 아래에 pipes 폴더 생성 후, board-status-validation.pipe.ts 파일 생성

board-status-validation.pipe.ts

import { ArgumentMetadata, PipeTransform } from '@nestjs/common';

export class BoardStatusValidationPipe implements PipeTransform {
  transform(value: any, metadata: ArgumentMetadata) {
    console.log('value', value);
    console.log('metadata', metadata);

    return value;
  }
}
  • value와 metadata를 로그로 찍어보는 pipe를 생성

Controller 코드

  @Patch('/:id/status')
  updateBoardStatus(
    @Param('id') id: string,
    @Body('status', BoardStatusValidationPipe) status: BoardStatus,
  ) {
    return this.boardsService.updateBoardStatus(id, status);
  }

게시물 상태 업데이트 하는 펑션에 @Body('status', BoardStatusValidationPipe) 를 추가한다.
(BoardStatusValidationPipe는 위에서 정의한 pipe 클래스다.)

결과


validation용 파이프 재정의

board-status-validation.pipe.ts

import { ArgumentMetadata, BadRequestException, PipeTransform } from '@nestjs/common';
import { BoardStatus } from '../Models/board.model';

export class BoardStatusValidationPipe implements PipeTransform {
  readonly StatusOptions = [BoardStatus.PRIVATE, BoardStatus.PUBLIC];

  private isStatusValid(status: any) {
    const index = this.StatusOptions.indexOf(status);
    return index !== -1;
  }

  transform(value: any) {
    value = value.toUpperCase();

    if (!this.isStatusValid(value)) {
      throw new BadRequestException(`${value} isn't in the status options`);
    }

    return value;
  }
}
  • StatusOptions로 BoardStatus의 PRIVATE, PUBLIC을 정의
  • isStatusValid()는 요청인자 status가 해당 StatusOptions의 값이 아니면 -1 리턴
  • transform에 isStatusValid의 리턴값이 -1일 경우, BadRequestException 예외 처리

결과값

profile
適者生存

0개의 댓글