저장을 습관화

NestJS - 인터셉터와 AOP 본문

공부/node.js

NestJS - 인터셉터와 AOP

ctrs 2023. 11. 9. 22:22

메모..

 

- 인터셉터

컨트롤러 다음에 어떠한 동작을 할때, 컨트롤러 시작 전과 시작 후 양 쪽을 조작할때 사용한다.

 

미들웨어와 비슷하지만 차이점은 미들웨어는 한번 끝나 컨트롤러로 돌아갔다면 이를 다시 조작하기 어렵다.

예를 들어 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까지의 기능에 필요한 공통된 기능을 제공하게 되었다.