updateData랑 movieData한테 타입을 부여하기 위해서 우리는 DTO(Data Transfer Object, 데이터 전송 객체)를 만들어야한다. 먼저 create-movie.dto.ts 파일을 만들자.
create-movie.dto.ts
export class CreateMovieDto {
readonly title: string;
readonly year: number;
readonly genres: string[];
}
그 다음 Controller 부분과 Service 부분에 타입을 추가해주자. (movieData)
Controller
@Post()
create(@Body() movieData : CreateMovieDto) {
return this.moviesService.create(movieData);
}
Service
create(movieData:CreateMovieDto) {
this.movies.push({
id: this.movies.length + 1,
...movieData
})
return true;
}
이렇게 해두면 아래와 같이 movieData. 만 입력해도 클래스가 가진 속성들이 자동으로 나와서 코딩하기에도 편리하다.
또한 타입에 대한 유효성을 검사할 수도 있다.
클래스의 유효성 검사를 위해 main.ts에 다음과같이 pipe를 만들어주겠다.
main.ts
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()
)
await app.listen(3000);
}
bootstrap();
또한 아래 명령어를 입력해서 npm 모듈을 설치하자.
$npm i class-validator class-transformer
그다음 아까 만들어두었던 dto파일에 다음과같이 데코레이터를 추가하자.
create-movie.dto.ts
import {IsString, IsNumber} from 'class-validator'
export class CreateMovieDto {
@IsString()
readonly title: string;
@IsNumber()
readonly year: number;
@IsString({each:true})
readonly genres: string[];
}
그 다음 postman에서 다음과 같이 POST 메소드로 {hacked: "by me"} 라는 body를 요청해보면 이런 결과창이 뜬다.
ValidationPipe 와 CreateMovieDto를 사용하고 있기 때문에 DTO의 타입을 실시간으로 확인할 수 있는 것이다.
ValidationPipe의 옵션 중 유용한 옵션인 whitelist라는 것이 있는데,
true로 설정하면 아무 Decoreator도 없는 어떠한 property의 object를 거룰 수 있다.
또한 보안을 위해 forbidNonWhitelisted 라는 옵션도 있다.
이는 정의를 하지 않은 데이터가 error메세지에 뜨게끔 도와준다
transform라는 옵션은
보통 데이터를 body로 받을 때 string으로 받아서 정수형은 parseInt를 써야 했지만,
그럴 필요 없이 바로 원하는 자료형으로 바꿔주는 기능을 한다.
여기까지 추가를 해보면
main.ts
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();
이렇게 되고, 추가했었던 parseInt를 바꿔주면 된다.
movies.controller.ts
import { Controller, Get, Param, Post, Delete, Patch, Body, Query } from '@nestjs/common';
import { CreateMovieDto } from './dto/create-movie.dto';
import { Movie } from './entities/movie.entity';
import { MoviesService } from './movies.service';
@Controller('movies')
export class MoviesController {
constructor(private readonly moviesService: MoviesService) {}
@Get()
getAll(): Movie[] {
return this.moviesService.getAll();
}
@Get('/:id')
getOne(@Param('id') movieId: number){
return this.moviesService.getOne(movieId)
}
@Post()
create(@Body() movieData : CreateMovieDto) {
return this.moviesService.create(movieData);
}
@Delete('/:id')
remove(@Param('id') movieId:number) {
return this.moviesService.deleteOne(movieId);
}
@Patch('/:id')
patch(@Param('id') movieId:number, @Body() updateData) {
return this.moviesService.update(movieId,updateData)
}
}
movies.service.ts
import { Injectable, NotFoundException } from '@nestjs/common';
import { NotFoundError } from 'rxjs';
import { CreateMovieDto } from './dto/create-movie.dto';
import { Movie } from './entities/movie.entity';
@Injectable()
export class MoviesService {
private movies: Movie[] = [];
getAll(): Movie[] {
return this.movies;
}
getOne(id:number): Movie {
const movie = this.movies.find(movie => movie.id === id);
if(!movie) {
throw new NotFoundException(" ID가 존재하지 않습니다. ")
}
return movie;
}
deleteOne(id:number) {
this.getOne(id)
this.movies = this.movies.filter(movie => movie.id !== id)
}
create(movieData:CreateMovieDto) {
this.movies.push({
id: this.movies.length + 1,
...movieData
})
return true;
}
update(id: number, updateData) {
const movie = this.getOne(id);
this.deleteOne(id)
this.movies.push({ ...movie, ...updateData})
}
}
'Back-End > Nest.js' 카테고리의 다른 글
Nest.js | REST API | Modules (0) | 2021.09.29 |
---|---|
Nest.js | REST API | DTOs and Validation(2) (0) | 2021.09.29 |
Nest.js | REST API | Movies Service(2) (0) | 2021.09.29 |
Nest.js | REST API | Movies Service(1) (0) | 2021.09.28 |
Nest.js | REST API | More Routes (0) | 2021.09.28 |