티스토리 뷰

웹 애플리케이션은 더 이상 정적인 페이지의 집합이 아닙니다. 실시간으로 변하는 주식 정보, 사용자의 클릭 한 번에 업데이트되는 장바구니, 그리고 끊임없이 쏟아지는 소셜 미디어 피드까지. 이 모든 동적인 움직임의 중심에는 비동기 네트워크 통신이 있습니다.
과거에는 XMLHttpRequest(XHR)라는 다소 복잡하고 장황한 도구를 사용해야 했지만, 현대 JavaScript는 Fetch API라는 세련되고 강력한 인터페이스를 제공합니다. 오늘은 단순히 데이터를 가져오는 수준을 넘어, 실무에서 마주치는 복잡한 네트워크 상황을 어떻게 우아하게 핸들링할 수 있는지 깊이 있게 파헤쳐 보겠습니다.
1. Fetch API의 핵심 메커니즘 (Deep Dive)
fetch()는 기본적으로 Promise 기반으로 동작합니다. 이는 "지금 당장은 아니지만, 미래의 어느 시점에 데이터를 줄게"라는 약속과 같습니다.
왜 Fetch를 써야 할까?
기존의 XHR이 콜백 지옥을 형성하며 코드의 가독성을 해쳤다면, Fetch는 체이닝(then, catch)과 async/await를 통해 마치 동기적인 코드처럼 읽히는 비동기 로직을 작성할 수 있게 해줍니다.
비유로 이해하는 Fetch
Fetch API를 사용하는 과정은 **'식당에서 음식을 주문하는 과정'**과 비슷합니다.
- 호출 (fetch): 메뉴판(URL)을 보고 종업원에게 주문을 넣습니다.
- 약속 (Promise): 종업원은 "주문이 접수되었습니다"라는 번호표를 줍니다. 아직 음식은 나오지 않았죠.
- 응답 처리 (response.json()): 주방에서 음식이 나오면(Response), 우리는 그것을 먹기 좋게 그릇에 옮겨 담는 과정(JSON 파싱)이 필요합니다.
- 사용: 이제 맛있게 식사(데이터 활용)를 합니다.
2. 실전 Hands-on: 이커머스 상품 대시보드 구현
단순한 console.log 예제 대신, 실제 이커머스 관리자 페이지에서 상품 목록을 불러오고 필터링하는 시나리오를 코드로 구현해 보겠습니다.
/**
* 이커머스 API로부터 상품 목록을 안전하게 가져오는 함수
* @param {string} category - 필터링할 카테고리
* @returns {Promise<Array>} - 상품 데이터 배열
*/
async function fetchProductDashboard(category = 'electronics') {
const API_URL = `https://fakestoreapi.com/products/category/${category}`;
try {
// 1. 네트워크 요청 시작
const response = await fetch(API_URL);
// 2. HTTP 상태 코드 검증 (중요!)
// fetch는 네트워크 오류가 아닌 이상 404, 500 에러에서도 catch로 가지 않습니다.
if (!response.ok) {
throw new Error(`HTTP Error! Status: ${response.status}`);
}
// 3. Response 객체의 본문(body)을 JSON으로 변환
const products = await response.json();
// 4. 비즈니스 로직 적용: 가격이 낮은 순으로 정렬하여 반환
return products.sort((a, b) => a.price - b.price);
} catch (error) {
// 5. 트러블슈팅: 네트워크 장애 또는 파싱 에러 처리
console.error("데이터 로드 중 문제가 발생했습니다:", error.message);
return []; // 빈 배열을 반환하여 UI 깨짐 방지
}
}
// 사용 예시
fetchProductDashboard('jewelery').then(data => {
console.log("정렬된 상품 데이터:", data);
});
💡 핵심 로직 분석
- response.ok: HTTP 상태 코드가 200~299 사이인지 확인하는 속성입니다. fetch는 서버가 에러를 반환해도 연결 자체에 성공하면 resolve되므로 이 체크가 필수입니다.
- await response.json(): HTTP 응답의 본문은 스트림 형태입니다. 이를 자바스크립트 객체로 변환하는 과정 또한 비동기로 이루어집니다.
3. 트러블슈팅: 흔히 겪는 함정들
네트워크 통신은 변수가 많습니다. 다음은 실무에서 자주 발생하는 이슈와 해결책입니다.
- CORS (Cross-Origin Resource Sharing): 보안상 이유로 다른 도메인의 리소스 요청이 차단되는 현상입니다. 서버 설정(Access-Control-Allow-Origin)을 변경하거나, 개발 단계에서는 프록시(Proxy) 서버를 활용해야 합니다.
- Time-out 설정: fetch는 기본적으로 타임아웃 기능이 없습니다. 요청이 무한정 대기하는 것을 막으려면 AbortController를 사용해야 합니다.
const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), 5000); // 5초 후 중단
fetch(url, { signal: controller.signal })
.then(res => res.json())
.catch(err => {
if (err.name === 'AbortError') console.log('요청 시간이 초과되었습니다.');
});
4. Trade-offs: Fetch vs Axios
현대 프로젝트에서 Fetch API 대신 Axios 라이브러리를 고민하는 경우도 많습니다. 어떤 선택이 옳을까요?
| 비교 항목 | Fetch API | Axios |
| 설치 | 내장 브라우저 API (설치 불필요) | 외부 라이브러리 설치 필요 |
| 브라우저 지원 | 구형 브라우저(IE) 미지원 | 광범위한 브라우저 지원 |
| 자동 JSON 변환 | response.json() 호출 필요 | 자동 변환 지원 |
| 요청 취소 | AbortController 활용 (다소 복잡) | CancelToken 등 직관적 기능 제공 |
결론적으로, 별도의 라이브러리 의존성을 줄이고 가벼운 프로젝트를 원한다면 Fetch를, 복잡한 요청 설정이나 구형 브라우저 지원이 필수라면 Axios가 합리적인 선택입니다.
마치며: 당신의 데이터는 안전한가요?
Fetch API는 단순히 데이터를 가져오는 도구를 넘어, 웹 애플리케이션의 사용자 경험(UX)을 결정짓는 핵심 관문입니다. 단순히 then을 나열하기보다, 발생 가능한 에러 케이스를 꼼꼼히 체크하고 사용자에게 "데이터를 불러오는 중입니다" 혹은 "네트워크를 확인해 주세요"와 같은 피드백을 주는 설계를 고민해 보시기 바랍니다.
- Total
- Today
- Yesterday
- react
- sLLM
- AI
- CSR
- java
- 엣지컴퓨팅
- LLM
- Rag
- HTML
- prompt engineering
- HBM
- 웹기초
- It용어
- TypeScript
- 구글
- on-device ai
- MSA
- CSS
- Nextjs
- Javascript
- 멀티모달
- 카카오
- 협력
- SSR
- 스마트안경
| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | |||
| 5 | 6 | 7 | 8 | 9 | 10 | 11 |
| 12 | 13 | 14 | 15 | 16 | 17 | 18 |
| 19 | 20 | 21 | 22 | 23 | 24 | 25 |
| 26 | 27 | 28 | 29 | 30 |