728x90
Pipe?
@Injectable()
로 주석이 달린 클래스- data transformation
- 입력 데이터를 원하는 형식으로 변환
- data validation
- 입력 데이터를 평가하고 유효성을 검사
- 메소드가 호출되기 직전에 파이프를 삽입하고 파이프는 메소드로 향하는 인수를 수신하고 이에 대해 작동
Binding Pipes
- Handler-level Pipes
- 핸들러 레벨에서
@UsePipes
를 이용해서 사용한다.
- 핸들러 레벨에서
- Parameter-level Pipes
- 파라미터 하나에만 해당
- Global Pipes
- 클라이언트에서 들어오는 모든 요청에 적용되며 bootstrap(main.ts) 코드에 삽입한다.
Built-in Pipes
- Nest JS의 기본적으로 사용할 수 있게 만들어 놓은 6가지 파이프
- ValidationPipe
- ParseIntPipe
- ParseBoolPipe
- ParseArrayPipe
- ParseUUIDPipe
- DefaultValuePipe
Set up
$ yarn add class-validator class-transformer
Validation Pipe
- handler level pipe
- 값 삽입시,
title
,description
값이 있는지 유효성 검사
📄 boards.controller.ts
...
@Post()
@UsePipes(ValidationPipe) // ADDED!
createBoard(@Body() createBoardDto: CreateBoardDto): Board {
return this.boardsService.createBoard(createBoardDto);
}
...
📄 create-board.dto.ts
import { IsNotEmpty } from 'class-validator';
export class CreateBoardDto {
@IsNotEmpty()
title: string;
@IsNotEmpty()
description: string;
}
⌛ Test
- request body
- HTTP/1.1 POST /boards
{
"title": "",
"description": ""
}
- response body
{
"message": [
"title should not be empty",
"description should not be empty"
],
"error": "Bad Request",
"statusCode": 400
}
에러 표출
- 예외 인스턴스를 생성해서 적용해준다.
- 다음과 같이 에러 인스턴스를 생성할 수 있다.
- 이때, 내가 원하는 메시지를 출력하려면 인자로 해당 메시지를 넣어준다.
getBoardById(id: string): Board {
const found = this.boards.find((board) => board.id === id);
if (!found) {
throw new NotFoundException(`Can't find Board with id ${id}`);
}
return found;
}
커스텀 파이프
PipeTransform
인터페이스를 새로 만들 커스텀 파이프에 구현해줘야한다.PipeTransform
인터페이스는 모든 파이프에서 구현해줘야하는 인터페이스이며 모든 파이프는transform()
을 필요로 한다.
- 커스텀 파이프
transform()
의 파라미터value
: 실제로 넘어오는 값metadata
: type, data와 같은 값
import { PipeTransform, ArgumentMetadata } from '@nestjs/common';
export class BoardStatusValidationPipe implements PipeTransform {
transform(value: any, metadata: ArgumentMetadata) {
console.log('value', value); // value what
console.log('metadata', metadata); // metadata { metatype: [Function: String], type: 'body', data: 'status' }
return value;
}
}
readonly class property
readonly
prefix?- 클래스 외부에서 접근은 할 수 있지만 변경은 하지 못한다.
커스텀 파이프 실제 구현하기
- 상태(status)가
PUBLIC
과PRIVATE
만 올 수 있게끔 커스텀 파이프를 생성한다.
📄 board-status-validation.pipe.ts
import { PipeTransform, BadRequestException } from '@nestjs/common';
import { BoardStatus } from '../boards.model';
export class BoardStatusValidationPipe implements PipeTransform {
readonly StatusOptions = [
BoardStatus.PRIVATE,
BoardStatus.PUBLIC
];
transform(value: any) {
value = value.toUpperCase();
if (!this.isStatusValid(value)) {
throw new BadRequestException(`${value} isn't a valid board status`);
}
return value;
}
private isStatusValid(status: any) {
const index = this.StatusOptions.indexOf(status); // 값이 없으면 -1 리턴
return index !== -1;
}
}
StatusOptions
로 일정한 값만 들어올 수 있게 정의한다.- 맞지 않는 값이 들어오게 되면
BadRequestException
리턴
- ❌ Error Case
- Request Body
{
"status": "what"
}
- Response Body
{
"message": "WHAT isn't a valid board status",
"error": "Bad Request",
"statusCode": 400
}
- ⭕ Correct Case
- Request Body
{
"status": "PRIVATE"
}
- Response Body
{
"id": "2887e410-1be1-11ee-9f95-21c62dc8381f",
"title": "test",
"description": "test description",
"status": "PRIVATE"
}
728x90
'🏠 Framework > NestJS' 카테고리의 다른 글
[NestJS] TypeORM (21) | 2024.01.15 |
---|---|
[NestJS] CRUD 구현 (0) | 2024.01.15 |
[NestJS] NestJS 기본 요소 (20) | 2024.01.15 |
[NestJS] Overview (0) | 2023.06.28 |