NestJS에서의 DTO

LeeJaeHoon·2021년 12월 4일
0
post-thumbnail
  • DTO
    • 데이터 전송 객체 (Data Transfer Object)
    • 어떠한 값이 어떤 타입을 가지고 이 값이 필수인지 옵션인지 정의하기위한 파일
    • npm i class-validator class-transformer
    • main.ts에 pipeline설정
      • express에서 검증 하는 미들웨어를 설정하는 것과 비슷하다고 생각하면 된다.

      • whiteList -> 엔티티 데코레이터에 없는 프로퍼티 값은 무조건 거름

      • forbidNonWhitelisted -> 엔티티 데코레이터에 없는 값 인입시 그 값에 대한 에러메세지 알려줌

        • 이 옵션을 true 시키면 dto에 정의되지 않은 프로퍼티를 body에 넘길시 property 'xxx' should not exist라는 에러가 뜨게 된다.
        • 즉, dto에 정의되지 않은 프로퍼티를 차단하기 위한 용도로 사용된다.
      • transform -> 컨트롤러가 값을 받을때 컨트롤러에 정의한 타입으로 형변환
        - 원래 param으로 들어오는 값은 무조건 string으로 들어온다.
        - 하지만 db에서 id는 uuid가 아닌 이상 대부분 number타입이다. 그래서 id를 params로 가져올 때 number로 형변환이 필요하다.
        - nest는 이런 불필요한 과정을 생략하기 위해 transform이라는 옵션을 만들었다.

        import { ValidationPipe } from '@nestjs/common';
        import { NestFactory } from '@nestjs/core';
        import { AppModule } from './app.module';
        
        async function bootstrap() {
          const app = await NestFactory.create(AppModule);
          app.useGlobalPipes(
            new ValidationPipe({
              whitelist: true,
              forbidNonWhitelisted: true,
              transform: true,
            }),
          );
          await app.listen(3000);
        }
        bootstrap();
      • transfrom 예시

        @Controller('movies') //movies라우터링 같음
        export class MoviesController {
          //매개변수 프로퍼티(Parameter Property) 를 이용하여 선언과 할당을 동시에 할 수 있습니다
          constructor(private readonly moviesService: MoviesService) {}
        
          @Get('/:id')
        	//원래는 id는 string이지만 movieId: number을 지정함으로 id의 타입은 number로 변환된다..
          getOne(@Param('id') movieId: number): Movie {
            console.log(typeof movieId);
            return this.moviesService.getOne(movieId);
          }
        }
      • create-movie.dto
        - @IsOptional()
        - 값이 empty(또는 null또는 undefined)일지라도 유효성검사를 무시하게 됩니다.

        import { IsNumber, IsString } from 'class-validator';
        
        export class CreateMovieDto {
          @IsString()
          readonly title: string;
          @IsNumber()
          readonly year: number;
        	// 배열이면 each true
        	@IsOptional()
          @IsString({ each: true })
          readonly genres: string[];
        }
    • 만든 dto를 controller에 적용
      • movies.controller.ts
        @Controller('movies') //movies라우터링 같음
        export class MoviesController {
          //매개변수 프로퍼티(Parameter Property) 를 이용하여 선언과 할당을 동시에 할 수 있습니다
          constructor(private readonly moviesService: MoviesService) {}
        
          @Post()
          create(@Body() movieData: CreateMovieDto) {
            return this.moviesService.create(movieData);
          }
        }
      • movie.service.ts
        @Injectable()
        export class MoviesService {
          private movies: Movie[] = []; //선언한 class내에서만 접근가능
        
          create(movieData: CreateMovieDto) {
            this.movies.push({
              id: this.movies.length + 1,
              ...movieData,
            });
          }
        }
      • update-movie.dto.ts
        • npm i @nestjs/mapped-types
          - PartialType
          - 입력 유형의 모든 속성이 선택 사항으로 설정된 유형(클래스)을 반환한다.(요구 사항: 각 속성에 최소 1개의 유효성 검사 데코레이터가 적용됨).

          import { PartialType } from '@nestjs/mapped-types';
          import { IsNumber, IsString } from 'class-validator';
          import { CreateMovieDto } from './create-movie.dto';
          
          export class UpdateMovieDto extends PartialType(CreateMovieDto) {}

0개의 댓글