배경

일반적인 요청 응답 생명주기.png

API 를 제작하기에 앞서 Request 와 Response를 컨트롤러가 받고 배출하기 과정 속에 위와 같이 미들웨어 → 가드 → 인터셉터 → 파이프 → 컨트롤러 → 인터셉터 → 예외 필터로 가는 라이프 사이클이 존재한다. 단순히 CRUD API를 작성하기 보다 API 전후 처리 작업들을 적절하게 사용하는 방법들을 같이 고민해보려고 한다. 또한, 미들웨어와 인터셉터에서 사용하는 예시를 보면 미들웨어에도 LoggerMiddleware가 존재하고 인터셉터에서도 LoggerInterceptor의 역할을 하는 요소들이 존재한다. Logger를 둘다 할 것인가 아니면 미들웨어가 하는게 나은지 인터셉터가 하는 것이 맞는지 아예 안하는지 고민해볼 필요가 있다.

사실 모든 서비스에 Logger를 붙이는 것이 맞는 것인가에 대해서도 우리 서비스와 백엔드 기술 스택에 따라서 처리해봐야 한다. 또한, 우리 서버 아키텍처를 보면 일반적인 API 서비스가 아닌 마이크로서비스를 기준으로 사용이 되고 있다. 이에 대해서 공부하고 조사해보자.

DRY(Don’t Repeat Yourself)

우리가 사용하는 Middleware, Interceptor 등등 중복된 역할을 하는 것이 존재할 것이다. 이를 복붙하지 말고 최대한 한 장소에서 해당 기능을 정의하고 전체를 커버할 수 있도록 하자.

Untitled

Middleware

Untitled

미들웨어는 라우트 핸들러가 클라이언트의 요청을 처리하기 전에 수행되는 컴포넌트이다.

기능

사용에 대한 고민

Express를 사용할 때의 미들웨어의 가장 주요한 역할은 쿠키파싱, 인증/인가 등의 요소로 사용하였다. 하지만 nest.js에서는 인증 인가의 역할을 주로 Guard에 맡기는 것을 권장한다. 그래서 우리가 미들웨어를 사용하기에 고민이 될 수도 있다. Nest.js에서 주로 미들웨어의 역할로 LoggerMiddleware를 제시하여 알려주었다. 사실 로깅이 왜 필요한지에 대한 의문이 들 수 있고 나도 그 생각을 했었다. 하지만 최근에 그 생각을 바꾸게 된 것이 클라이언트와 서버 간의 요청에 있어 요청이 여러 번 가는 케이스가 생기게 되었다. 이 요소가 클라이언트에서의 코드 문제인지 서버에서의 코드 문제인지 길피를 잡아 준 것이 바로 로그였다. 우리 서비스에서 로그가 필요한 부분이 어디에 있을까? MSA 에서 Gateway와 하이브리드 어플리케이션을 사용할 때 해당 요소를 HTTP로 호출하는 부분에 대하여 적용하면 될 것 같다. 그러나 로그를 적용함에 있어 Gateway와 Microservice에서 정의한 Controller 코드가 다른 것을 인지해야 한다.

  1. Gateway : 전역 상태로 모든 라우팅에 적용

  2. 하이브리드 어플리케이션이 Microservices : HTTP로 요청이 되는 요소에 적용

    HTTP 요청이 적용되는 요소란?

    다 적용이 되는거 아니야? 라고 생각할 수 있다. 하지만 마이크로서비스에서의 코드와 데코레이터가 아래와 같이 다르다. 또한, 현재는 TCP 통신을 하고 있지만 속도를 높이기 위하여 Redis나 Kafka를 도입할 수 있기에 다르게 해야 한다.

Interceptors