저장을 습관화
NestJS - 인터셉터와 AOP 본문
메모..
- 인터셉터
컨트롤러 다음에 어떠한 동작을 할때, 컨트롤러 시작 전과 시작 후 양 쪽을 조작할때 사용한다.
미들웨어와 비슷하지만 차이점은 미들웨어는 한번 끝나 컨트롤러로 돌아갔다면 이를 다시 조작하기 어렵다.
예를 들어 res.json으로 내보낸 데이터를 다시 한 번 더 사용하고 싶은 상황이 와도 구현해내기가 복잡하다.
인터셉터는 내가 어떠한 응답을 보냈을때 그 응답을 마지막으로 한 번 더 조작을 할 수 있게 된다
다시 말해 컨트롤러에서 리턴한 데이터를 마지막으로 한 번 더 가공할 수 있다
익스프레스에서는 이러한 인터셉터 기능이 없다.
예시) undefinedToNull.interceptor.ts
import {
CallHandler,
ExecutionContext,
Injectable,
NestInterceptor,
} from '@nestjs/common';
import { Observable, map } from 'rxjs';
@Injectable()
export class UndefinedToNullInterceptor implements NestInterceptor {
intercept(
context: ExecutionContext,
next: CallHandler<any>,
): Observable<any> | Promise<Observable<any>> {
// 컨트롤러로 돌아가기 전 수행할 동작
// 컨트롤러가 실행되고 난 후 수행할 동작은 next.handle() 다음에 작성
return next
.handle()
.pipe(map((data) => (data === undefined ? null : data)));
}
}
/**json에서 null은 취급하나
* undefined는 취급하지 않아 에러가 발생할 수 있다.
* 이를 방지하기 위해서 만약 값이 undefined일 경우
* 값을 null로 바꿔주는 기능을 하는 인터셉터이다.
*/
// implements
// 타입등을 정확하게 지켜서 구현할 수 있도록 도와주는 역할
// 임플리먼츠가 있다면 인터셉터 내용에 intercept만 입력하고 자동 완성으로 만들 수 있음
user.controller.ts
// ...
import { UndefinedToNullInterceptor } from 'src/common/interceptors/undefinedToNull.interceptor';
@UseInterceptors(UndefinedToNullInterceptor)
// 인터셉트를 라우터 전체에 적용하고 싶다면 최상단에
// 특정 라우터에만 적용하고 싶다면 그 곳에 입력
@ApiTags('USER')
@Controller('api/users')
export class UsersController {
constructor(private readonly usersService: UsersService) {}
// ...
}
- AOP(Aspect Oriented Programming, 관점 지향 프로그래밍)
AOP는 '공통된 기능을 재사용하는 기법'이라고 정리할 수 있다.
그리고 Nest에서 인터셉터가 이 AOP 역할을 담당하고 있다.
예를 들어, 아래와 같이 4개의 기능이 있다고 하자
1. A -> B -> C -> D
2. A -> E -> D
3. A -> G -> H -> D
4. A -> I -> D
4개의 기능에는 공통적인 관심사 A와 D가 있다.
이 A를 인터셉터의 '컨트롤러로 돌아가기 전 수행할 동작' 부분에 넣고,
D를 '컨트롤러가 실행되고 난 후 수행할 동작, next.handle() 다음에 작성'에 넣음으로써 코드의 중복을 해결한다.
그 외 1.의 'B -> C', 2.의 'E', 3.의 'G -> H', 4.의 'I'가
'A가 수행한 후', 'D가 수행하기 전'에서 말하는 컨트롤러가 된다.
이러한 흐름으로 인터셉터가 1부터 4까지의 기능에 필요한 공통된 기능을 제공하게 되었다.
'공부 > node.js' 카테고리의 다른 글
에러 기록 - Could not resolve dependency: @nestjs/typeorm@"*" from the root project (0) | 2023.11.11 |
---|---|
NestJS - 컨트롤러 constructor에 private readonly를 설정하는 이유 (0) | 2023.11.09 |
NestJS - DTO를 인터페이스가 아닌 클래스로 선언하는 이유 (0) | 2023.11.06 |
NestJS - tsconfig.json의 "esModuleInterop" 옵션 (0) | 2023.11.04 |
NestJS - hot reload (0) | 2023.11.04 |