Node.js 18 LTS 전환하면서 fetch API 도입한 경험
배경
2022년 10월 25일 Node.js 18이 LTS로 전환되었다. 기존 16 버전을 사용하던 프로젝트들을 점진적으로 업그레이드하기로 결정했다.
가장 눈에 띄는 변화는 fetch API가 기본 탑재되었다는 점이다. 그동안 node-fetch나 axios를 의존성으로 추가해서 사용했는데, 이제 별도 설치 없이 사용할 수 있게 되었다.
마이그레이션 전략
전면 교체는 리스크가 크다고 판단해서 신규 기능부터 fetch를 사용하기로 했다.
기존 axios 코드:
const axios = require('axios');
const response = await axios.get('https://api.example.com/data', {
headers: { 'Authorization': `Bearer ${token}` }
});
const data = response.data;
fetch로 전환:
const response = await fetch('https://api.example.com/data', {
headers: { 'Authorization': `Bearer ${token}` }
});
const data = await response.json();
주의할 점
axios와 다르게 fetch는 HTTP 에러 상태 코드에서 reject하지 않는다. 404나 500이 와도 promise는 resolve된다. response.ok를 확인하는 로직이 필수다.
const response = await fetch(url);
if (!response.ok) {
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
}
const data = await response.json();
또한 timeout 설정이 기본 제공되지 않는다. AbortController를 사용해야 한다.
const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), 5000);
try {
const response = await fetch(url, { signal: controller.signal });
// ...
} finally {
clearTimeout(timeoutId);
}
결과
신규 마이크로서비스 2개에 fetch를 적용했다. axios 의존성이 사라지면서 번들 크기가 약간 줄었고, 브라우저와 서버의 API가 통일되어 코드 일관성이 높아졌다.
기존 서비스는 당분간 axios를 유지할 예정이다. 동작하는 코드를 굳이 바꿀 필요는 없다고 판단했다.