드디어(?) npm에 첫 오픈소스를 배포한 기념으로 글을 작성한다.
# 개발 이유
회사에서 맡고 있는 프로젝트 중 하나인 예약서버를 리팩토링하던 중,
메인으로 쓰고있는 API Request 라이브러리인 axios를 내 방식대로 업그레이드 하고 싶은 욕구가 샘솟았다.
그 이유는 바로 Retry 처리 때문인데,
그때 당시의 나는 요청에서 에러가 날 경우 귀찮음과 일단 빨리 개발하자는 마인드를 핑계삼아 try catch로 Retry 처리를 했다.
const callAPI = async () => {
try {
// 첫 번째 api 요청!
const firstTry = await axios.get("API URL");
// 성공하면 이것저것 해야지...
doSomething(firstTry);
} catch (err) {
// 헐 요청이 실패했네,, 로그는 남겨놔야지...
logger.info(`첫 시도가 실패해서 리트라이 한다. ${err.message}`);
// 근데 네트워크 연결이 잠깐 안된 거일 수도 있으니까 Retry는 해야지!
try {
// 두 번째 api 요청!
const secondTry = await axios.get("API URL");
// 성공하면 이번에 진짜 이것저것 해야지...
doSomething(secondTry);
} catch (err) {
// 헐 두번째 요청도 실패했네 어쩔 수 없지 그냥 에러 처리하자...
logger.error(`대충 에러로그 ${err.message}`);
}
}
};
정말 믿기지 않겠지만,, 위의 코드 예시는 실제로 적용했었던 나의 감동 실화이다... 😂😂
저 방식이 안좋은 점은 같은 코드가 반복되며 Retry 횟수를 2번이상 늘리기 쉽지도 않다.
(try catch를 노가다로 계속 반복하면 가능은 하다.. 콜백 지옥이 아닌 try 지옥?!)
이와 같은 문제점을 해결하기 위해 axios에 Retry 기능이 추가된 angxios를 직접 개발하기로 결정했다.
한국말로는 앙시오스이다. (앵시오스 아님!)
사실, 같은 니즈를 느끼는 사람들이 많았는지 axios에 Retry기능을 추가해 배포한 모듈이 꽤 있었다.
하지만 사용방법이 마음에 안 들기도 했고, 오픈소스 생태계에 기여해 보고 싶었기에 내 입맛대로 만들게 되었다.
# 개발 과정
개발 과정이 그렇게 딥하지는 않았다.
가벼운 기능일뿐더러 기존의 axios를 래핑하고 Retry 기능 추가만 하면 됐기 때문이다.
먼저, axios 래핑에 용이한 ES의 Class로 메인 모듈을 작성했고 IIFE로 싱글톤을 구현했다.
const Angxios = new (class {
// 각종 멤버 변수들...
// 각종 래핑 메소드들...
})();
export default Angxios;
핵심 로직인 Retry 구현은 interceptor를 통해 구현했다.
어떻게 Retry를 구현할지 고민을 정말 많이 했는데, 마침 interceptor라는 개념을 알게 되어 적용해 보았다.
내 경험상, middleware와 비슷한 인상을 받았는데 Request를 날리기 전과, Response를 받기 전에 컨텍스트를 가로채 제어할 수 있었다.
angxios에서는 이를 이용해 Request를 날리기 전 사용자가 설정한 retryCount를 요청에 낑겨보내고, 만약 에러가 발생하면 Response를 받기 전 요청에 기록되어 있는 retryCount를 1씩 감소시켜 0이 될때까지 Retry하는 식으로 구현했다.
이 방식에 대한 효율성과, 사용자들이 내가 적용한 파라미터 이름을 사용하면 어쩌지?라는 의문이 들었지만,
요청에 파라미터 하나 추가된다고 해서 성능이 저하될 것 같진 않고, retryCount를 저장할 Namespace를 angxios로 지정했기에 이 방식을 채택했다.
또한, 사소하지만 몇 가지 발목을 잡는 부분이 있었는데 모듈 시스템(CommonJS, ES 등)과 TS 지원이었다.
이를 위해, babel과 d.ts를 적용하여 해결했다.
# 배포
- 버전 1 배포 첫 주 1100 다운로드를 돌파했다!
'Language & Runtime > Node.js' 카테고리의 다른 글
[Node.js] Event Loop를 파헤쳐 보자 (0) | 2022.12.05 |
---|