클라이언트에서 보내온 값들은 핸들러에서 어떻게 가져오나요?
Express에서는 bodyParser 모듈을 이용해서
req.body로 클라이언트에서 보내온 값을 받아왔습니다.
이렇게 하면 모든 request에서 보내온 값을 가져올 수 있으며, 하나씩 가져 오려면
@Body('title') title 혹은 @Body('description') description로 가져오면 됩니다
DTO
DTO (Data Transfer Object)는 무엇인가요?
계층간 데이터 교환을 위한 객체입니다.
DB에서 데이터를 얻어 Service나 Controller 등으로 보낼 때 사용하는 객체를 말합니다.
DTO는 데이터가 네트워크를 통해 전송되는 방법을 정의하는 객체입니다.
interface나 class를 이용해서 정의 될 수 있습니다. (하지만 클래스를 이용하는것을 Nest JS에서는 추천하고 있습니다)
DTO (Data Transfer Object)를 쓰는 이유는 무엇인가요?
- 데이터 유효성을 체크하는데 효율적입니다.
- 더 안정적인 코드로 만들어 줍니다. 타입스크립트의 타입으로도 사용됩 니다.
Nest JS에서 데이터 처리의 흐름을 보면...
Board를 위한 Property들을 여러 곳에서 사용하고 있습니다. ( title, description..)
지금은 간단한 애플리케이션을 만들기 떄문에 몇개의 프로퍼티만 불러 주 고 몇군데에서만 불러 주면 됩니다.
하지만 정말 많은 프로퍼티를 갖고 정 말 여러군데에서 이용하며 갑자기 한곳에서 Property 이름을 바꿔줘야한다 면 어떻게 해야할까요?
그러면 다른 곳에 똑같이 쓰인 모든 곳의 프로퍼티도 똑같이 바꿔줘야 합니다
Interface VS Class For DTO
DTO 는 Interface나 Class를 사용해서 만들면 됩니다. 하지만 Class가 더 선호됩니다. 선호되는 이유는 ?
TypeScript 인터페이스를 사용하거나 간단한 클래스를 사용하여 DTO 스키마를 결 정할 수 있습니다.
흥미롭게도 여기에서 Class를 사용하는 것이 좋습니다.
왜? 클래 스는 JavaScript ES6 표준의 일부이므로 컴파일 된 JavaScript에서 실제 엔티티로 유지됩니다.
반면에 TypeScript 인터페이스는 트랜스 파일 중에 제거되므로 Nest는 런타임에서 참조 할 수 없습니다.
이것은 파이프와 같은 기능을 런타임에서 사용할 수 있기 때문에 런타임에서 사용 될 수 있는게 중요합니다.
그래서 DTO는 CLASS를 이용해서 만들겠습니다.
Pipe 이용
Pipe은 무엇인가요?
파이프는 @Injectable () 데코레이터로 주석이 달린 클래스입니다.
파이프는 data transformation과 data validation을 위해서 사용됩니다.
파이프는 컨트롤러 경로 처리기에 의해 처리되는 인수에 대해 작동합니다.
Nest는 메소드가 호출되기 직전에 파이프를 삽입하고 파이프는 메소드로 향하는 인수를 수신하고 이에 대해 작동합니다.
Data Transformation?
입력 데이터를 원하는 형식으로 변환 (예 : 문자열에서 정수로)
만약 숫자를 받길 원하는데 문자열 형식으로 온다면 파이프에서 자동으로 숫자로 바꿔줍니다.
EX) String to Integer. string '7' => Integer 7
Data validation?
입력 데이터를 평가하고 유효한 경우 변경되지 않은 상태로 전달하면됩니다.
그렇지 않으면 데이터가 올바르지 않을 때 예외를 발생시킵니다.
만약 이름의 길이가 10자 이하여야 하는데 10자 이상 되면 에러를 발생시킵니다.
파이프는 위에 두가지 모든 경우에서....
라우트 핸들러(Route Handler)가 처리하는 인수에 대해서 작동합니다.
그리고 파이프는 메소드를 바로 직전에 작동해서 메소드로 향하는 인수에 대해서 변환할 것이 있느면
변환하고 유효성 체크를 위해서도 호출됩니다.
PIPE 사용하는 법(Binding Pipes)
파이프를 사용하는 방법(Binding pipes)은 세가지로 나눠질수 있습니다.
Handler-level Pipes ,Parameter-level Pipes, Global-level Pipes 입니다
이름에서 말하는 것 그대로 핸들러 레벨, 파라미터 레벨, 글로벌 레벨로 파이프 사용 할 수 있습니다.
1. Handler-level Pipes
핸들러 레벨에서 @UsePipes() 데코레이터를 이용해서 사용 할 수 있습니다.
이 파이프는 모든 파라미터에 적용이 됩니다. (title, description)
2. Parameter-level Pipes
파라미터 레벨의 파이프 이기에
특정한 파라미터에게만 적용이 되는 파이프 입니다.
아래와 같은 경우에는 title만 파라미터 파이브가 적용이 됩니다.
3. Global Pipes
글로벌 파이프로서 애플리케이션 레벨의 파이브 입니다.
클라이언트에서 들어오는 모든 요청에 적용이 됩니다.
가장 상단 영역인 main.ts에 넣어주시면 됩니다.
Built-in Pipes
Nest JS 에 기본적으로 사용할 수 있게 만들어 놓은 6가지의 파이프가 있습니다.
- ValidationPipe
- ParseIntPipe
- ParseBoolPipe
- ParseArrayPipe
- ParseUUIDPipe - DefaultValuePipe
이름을 보면 각각의 파이프가 어떠한 역할을 하는지 짐작을 할 수 있습니다.
그중에서 ParseIntPipe를 이용해서 간단히 파이프를 체험해보겠습니다.
이렇게 원래는 파라미터 값으로 숫자가 와야하는 핸들러가 있습니다..
하지만 파라미터 값으로 숫자가 아닌 abc 문자열을 보냅니다.
파이프를 이용한 유효성 체크
필요한 모듈
class-validator , class-transformer
npm install class-validator class-transformer --save
Documentation 페이지
- https://github.com/typestack/class-validator#manual-validation
파이프 생성하기
현재는 게시물을 생성할 때 이름과 설명에 아무런 값을 주지 않아도 아무 문제 없이 생성이 됩니다.
이 부분을 파이프를 이용해서 수정해주겠습니다.
특정 게시물을 찾을 때 없는 경우 결과 값 처리
현재 특정 게시물을 ID로 가져올 때 만약 없는 아이디의 게시물을 가져오려고 한다면 결과값으로 아무 내용이 없이 돌아옵니다.
그래서 그 부분을 게시물이 없는 것이면 없다고 내용을 넣어서 클라 이언트로 보내주겠습니다.
에러를 표출해주기 위해서는 ...
찾는 게시물이 없을 때는 예외 인스턴스를 생성해서 이용해주시면 됩니다.
커스텀 파이프를 이용한 유효성 체크
커스텀 파이프 구현 방법
먼저 PipeTransform이란 인터페이스를 새롭게 만들 커스텀 파이프에 구현해줘야 합니다.
이 PipeTransform 인터페이스는 모든 파이프에서 구현해줘야 하는 인터페이스입니다.
그리고 이것과 함께 모든 파이프는 transform() 메소드를 필요합니다.
이 메소드는 NestJS가 인자 (arguments)를 처리하기 위해서 사용됩니다.
이 메소드는 두개의 파라미터를 가집니다.
첫번째 파라미터는 처리가 된 인자의 값(value)이며
두번째 파라미터는 인자에 대한 메타 데이터를 포함한 객체입니다.
transform()메소드에서 Return 된 값은 Route 핸들러로 전해지며
만약 예외(Exception)가 발생하면 클라이언트에 바로 전해집니다.
실제로 value 와 metadata값 콘솔로 찍어보기
1. 커스텀 파이프 생성 2. 게시물에 업데이트하는 핸들러에 커스텀 파이프 넣어주기 3. 포스트 맨으로 요청 보내기
파라미터 Level에서 pipe를 넣어주었다.
커스텀 파이프로 실제 기능 구현하기
구현 할 기능 : 상태(Status)는 PUBLIC과 PRIVATE만 올 수 있기 때문에 이외의 값이 오면 에러를 보내주겠습니다.
readonly class property
접두사(prefix) readonly는 속성을 읽기 전용으로 만드는 데 사용됩니다.
읽기 전용 멤버는 클래스 외부에서 액세스 할 수 있지만 해당 값은 변경 할 수 없습니다
유저 데이터 유효성 체크
원하는 에러 메시지 설정하기
현재 비밀번호가 유효성체크에 걸리면 엄청 긴 에러메시지가 나 옵니다.
이 부분은 원하는 메시지로 나올수있게 설정해주겠습니다
'모카 스터디 > Nest' 카테고리의 다른 글
Nest JS JWT/Passport 인증/인가 [John Ahn] (0) | 2023.07.30 |
---|---|
Nest JS TypeORM 연동 [John Ahn] (0) | 2023.07.30 |
Nest JS 기본 [John Ahn] (0) | 2023.07.30 |
slack_nest_study_zerocho (0) | 2023.05.07 |
노마드 nestjs API만들기 (0) | 2023.04.11 |