Express 를 사용하면 body data 혹은 param 에 유효하지 않은 값을 받을 것을 대비해서 일일이 유효성 검사를 해줘야 하는 불편함이 존재한다. 하지만 NestJS 는 아주 쉽게 유효성 검사를 할 수있게 도와주며 심지어 내가 원하는 데이터의 타입이 아닌 데이터가 들어오는 것도 방지할 수 있다. 간단하게 맛보기로 어떻게 사용할 수 있는지 알아보자.
$ npm i class-validator class-transformer
위의 라이브러리들을 설치 한 후 src/users/dto 경로에 create-user.dto.ts 생성.
// create-user.dto.ts
import { IsString } from 'class-validator';
export class CreateUserDto {
@IsString()
name: string;
@IsString()
address: string;
@IsString({ each: true })
hobbies: string[];
}
소스만 봐도 무엇을 원하는지 알 것 같다. 그리고 main.ts 에 아래와 같이 app 객체에 useGlobalPipes 를 추가. express 에서 middleware 를 사용하는 것이라고 생각하면 된다.
// 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, // decroator 가 없는 property 는 걸러서 받음.
forbidNonWhitelisted: true, // whiltelist 에 해당하는 데이터를 보내면 에러를 발생시킴.
transform: true, // param 을 내가 원하는 타입으로 변경해줌.
}),
);
await app.listen(3000);
}
bootstrap();
그리고 Controller 와 Service 에 타입을 추가해 주자.
// users.controller.ts
import { Body, Controller, Delete, Get, Param, Post } from '@nestjs/common';
import { CreateUserDto } from './dto/create-user.dto';
import { UsersService } from './users.service';
@Controller('users')
export class UsersController {
constructor(private readonly usersService: UsersService) {}
@Get()
getAllUser() {
return this.usersService.getAllUser();
}
@Get(':id')
getUserById(@Param('id') userId: number) {
return this.usersService.getUserById(userId);
}
@Delete(':id')
deleteByUserId(@Param('id') userId: number) {
return this.usersService.deleteByUserId(userId);
}
// userInfo 타입을 DTO 로 지정!
@Post()
createUser(@Body() userInfo: CreateUserDto) {
console.log('userInfo :', userInfo);
return this.usersService.createUser(userInfo);
}
}
// users.service.ts
import { Injectable } from '@nestjs/common';
import { CreateUserDto } from './dto/create-user.dto';
import { User } from './entity/users.interface';
@Injectable()
export class UsersService {
private users: User[] = [];
getAllUser(): User[] {
return this.users;
}
getUserById(userId: number): User {
return this.users.find((user) => user.id === userId);
}
deleteByUserId(userId: number): boolean {
this.users = this.users.filter((user) => user.id !== userId);
return true;
}
// userInfo 에 DTO 타입 지정!
createUser(userInfo: CreateUserDto) {
const newUser = {
id: this.users.length + 1,
...userInfo,
};
this.users = [...this.users, newUser];
return '새로운 유저 생성!';
}
}
변경 된 코드는 새로운 User 를 생성하는 부분에 타입을 지정해 준 것이 전부.
테스트 결과는 위와 같다. 참고로 forbidNonWhitelisted 를 사용하지 않고 whitelist 만 사용할 경우 위와 같이 데이터를 보내면 올바르게 전송되는데 대신 DTO 에 정의 되지 않은 nao 는 제외되어 들어오게 된다. forbidNonWhitelisted 는 애초에 DTO 에 정의 되지 않은 속성값이 존재 할 경우 바로 에러를 발생시킨다.
그리고 localhost:3000/users/1 로 GET 요청을 보내면 Param 의 id 의 타입은 String 으로 들어오게 된다. 그러나 아래와 같이 Param 의 타입을 number 로 변경해주면 number 로 들어오게 된다. 이 기능을 사용하기 위해서는 validationPipe 속성에 trasnform 을 true 로 설정해 주어야 한다. express 를 사용할 때면 param 의 값을 일일이 형변환을 해주었어야 했는데 NestJS 를 사용하면 그럴 필요도 없고 아주 간편하다.
...
getUserById(@Param('id') userId: number) {
console.log(typeof userId); // number
return this.usersService.getUserById(userId);
}
...
참고
'Development > NestJS' 카테고리의 다른 글
NestJS + TypeORM + Migration 설정 (0) | 2021.02.01 |
---|---|
NestJS 코드 변경이 적용되지 않을 때 해결법 (0) | 2021.01.06 |
[NestJS] 간단하게 일단 맛보기 #2 (0) | 2020.12.30 |
[NestJS] 간단하게 일단 맛보기 #1 (0) | 2020.12.29 |
최근댓글