최근 비즈니스 로직을 수정하던 중, 라이브러리로만 적용하던 Express의 Middleware를
커스터마이즈해서 유용하게 사용했기에 기록으로 남긴다.
# Middleware란?
참조 : Express 공식문서
공식문서를 요약하자면, 미들웨어란 request-response cycle 도중 요청과 응답의 중간에서 목적에 맞게 로직을 처리할 수 있는 기능이다.
보통 Express를 서버 스택으로 가져가면 body-parser, multer, cors 등과 같은 라이브러리들을 알게 모르게 미들웨어로 낑겨 사용하며, Access 로깅을 할 때에도 미들웨어는 유용하게 쓰인다.
내 경험상 Django를 사용할 때 적용하는 데코레이터 패턴과 유사한 것 같다. (API 매핑 용으로..)
# Middleware 적용
그렇다면, 나는 미들웨어를 어디에 어떻게 적용했을까?
우선 부딪힌 문제는 다음과 같다.
어떤 이벤트가 발생할 때마다 콜백을 주는 외부 SaaS 플랫폼을 연동할 예정인데, 해당 플랫폼에서 콜백 URL을 하나밖에 지원하지 않아 Prod 스테이지로 배포를 하는 순간 Dev 스테이지에서 콜백을 더 이상 받지 못하게 된다.
위 문제를 해결하기 위한 방법으로, Prod 서버에서 개발용 콜백을 받을 경우 그 콜백을 Dev 서버로도 흘려주는 방식을 채택했고 이를 미들웨어로 구현했다.
코드 예시는 다음과 같다.
if (process.env.STAGE === "prod") {
app.use(
"/SaaS에 등록한 콜백 URL",
(
req: express.Request,
res: express.Response,
next: express.NextFunction
) => {
const callbackInfo: CallbackInfo = req.body;
if (
테스트 이벤트로 발생한 콜백인가?
) {
axios
.post(`Dev 서버 URL${req.originalUrl}`, callbackInfo)
.then((response: any) => {
logger.info(
`Dev 서버로 잘 흘려보냈다람쥐 :), ${req.originalUrl}`
);
})
.catch((error: any) => {
logger.error(
`Dev 서버로 못 흘려보냈다람쥐 :(, ${error.message}`
);
});
}
next();
}
);
}
한 가지 주의할 점은, 미들웨어를 Prod 서버에만 적용시켜야 한다는 것인데,
만약 Dev 서버에도 적용할 경우...
> Prod 서버 => Dev 서버 => Dev 서버 => Dev 서버 ... Dev 서버 => 꽥
위와 같이 요청이 무한 반복되는 참사가 일어날 수 있다.
또한, Request 객체의 originalUrl 필드를 사용하면, 콜백 URL을 동적으로 대처할 수 있다.