// logger.middleware.ts
use(request: Request, response: Response, next: NextFunction): void {
const { ip, method, originalUrl, query, body } = request;
const userAgent = request.get('user-agent') || ''; // header에서 가져옴
// 응답이 끝났을 때
response.on('finish', () => {
const { statusCode } = response;
const contentLength = response.get('content-length');
this.logger.info(`{
info : `${method} ${originalUrl} ${statusCode} ${contentLength} - ${userAgent} ${ip}`,
query : `${JSON.stringify(query)}`,
body : `${JSON.stringify(body)}`
}`);
});
next();
미들웨어는 라우터 핸들러에 도착전에 실행되는 함수로 요청에 대한 처리를 제어할수 있다
요청 로깅, 요청에러 헨들러, 요청 인증 등..
하지만 요청과 응답사이에 동작하는 개념으로 난 response데이터 및 응답시간 까지 찍고 싶어서 interceptor에서 요청과 응답에 대한 모든 로그를 찍고자 했다
// logger.middleware.ts
const now = Date.now();
return next
.handle()
.pipe(
map(data => {
const { ip, method, originalUrl, query, body } = context.switchToHttp().getRequest();
logger.info('[REQUEST AND RESPONSE]',{
message: `
requestInfo:
[ip method url] ${ip}, ${method}, ${originalUrl},
[query] ${JSON.stringify(query)},
[body] ${JSON.stringify(body)}
data: ${JSON.stringify(data)}
statusCode: ${context.switchToHttp().getResponse().statusCode}
executeTime: ${Date.now()-now} ms
`,
})
})
);
[2023-07-29 12:08:07] DEV.info: [REQUEST AND RESPONSE]
requestInfo:
[ip method url] 127.0.0.1, GET, /v1/code-item/app-menu,
[query] {},
[body] {}
data: [{"id":17,"key":"Dashboard","value":"/#","description":null,"isDeleted":"N","order":0},{"id":15,"key":"Trendy Discussions","value":"/trendy/discussions","description":null,"isDeleted":"N","order":1},{"id":16,"key":"Community","value":"/commu-bot","description":null,"isDeleted":"N","order":2}]
statusCode: 200
executeTime: 12 ms
위와 같이 요청 - 응답 사이의 각 처리단계에서 세밀하게 조정할수 있다
interceptor의 동작과정
- 요청 수신: 사용자로부터의 요청이 서버에 도착합니다. 이 시점에서 Interceptor는 아직 작동하지 않습니다.
- 전처리 Interceptor: NestJS는 등록된 Interceptor 중에서 해당 요청을 처리하는 라우트 핸들러에 연결된 Interceptor를 찾습니다. 그런 다음, 이 Interceptor의
intercept()
메서드가 호출됩니다. 이 메서드는 전처리 단계에서 실행되며, 요청을 가로채거나 요청 데이터를 수정하거나, 특정 검증 로직을 수행할 수 있습니다. - 라우트 핸들러 처리: 전처리 Interceptor가 요청을 변경하거나 차단하지 않는다면, 요청은 해당 라우트 핸들러로 전달됩니다. 라우트 핸들러는 요청 데이터를 사용하여 필요한 처리를 수행하고, 응답 데이터를 생성합니다.
- 후처리 Interceptor: 라우트 핸들러가 처리를 완료하고 응답 데이터를 생성하면, 후처리 Interceptor가 작동합니다. 후처리 Interceptor는 응답 데이터를 받아 데이터를 변경하거나, 추가적인 처리를 수행할 수 있습니다.
- 응답 송신: 모든 Interceptor와 라우트 핸들러 처리가 완료되면, 서버는 최종 응답 데이터를 사용자에게 송신합니다.
- 미들웨어는 HTTP관련 작업 쿠키 헤더 파싱 등에서 사용
- interceptor 비즈니스 로직 관련에 사용에서 활용하기 좋음