안녕하세요 😘
웹파트 OB 이예림입니다!
저는 API를 붙인다! 하면 당연하게 Axios를 사용하곤 했는데요, 기본 제공되는 Fetch메서드가 아닌 당연하다는듯이 axios를 쓰는 저를 보고 성희OB가 본 주제를 추천해주어 공부해보게 되었습니다!
우리는 Axios와 Fetch를 사용하여 API 통신을 구현할 수 있습니다. 각각 고유한 장점과 특징을 가지고 있지만, 그 설계 철학에서 큰 차이를 보이는데요! 이번 글에서는 Axios와 Fetch의 주요 차이점을 간략히 살펴보고, 그 중에서도 에러 핸들링에 대해 딥다이브 해본 후, 마지막으로 장단점을 정리하여, 실제 프로젝트에서 어떤 상황에 더 적합한지 알아보겠습니다.
📌 Axios와 Fetch의 주요 차이점
1️⃣ 기본 설정의 편의성
- Axios
import axios from 'axios'; axios.post('//url', { title: 'Axios Test', body: 'This is a test', userId: 1 }).then(response => { console.log(response.data); }).catch(error => { console.error('Error:', error); });
- : 기본적으로 Content-Type: application/json 을 자동 설정해주고, 객체 형태로 구성된 데이터를 JSON 문자열로 자동 변환해 준다.
- Fetch
fetch('// url', { method: 'POST', headers: { **'Content-Type': 'application/json' // 직접 설정 필요** }, body: **JSON.stringify**({ title: 'Fetch Test', body: 'This is a test', userId: 1 }) }) .then(response => response.json()) .then(data => console.log(data)) .catch(error => console.error('Error:', error));
- : Content-Type 설정 및 데이터 변환을 수동으로 해야 한다. 사용자가 더 많은 작업을 해야 하는 경우가 있다.
2️⃣ 응답 데이터 자동 파싱
- Axios
import axios from 'axios'; const fetchDataWithAxios = async () => { try { const response = await axios.get('//url'); console.log(response.data); // 이미 파싱된 JSON 데이터 } catch (error) { console.error('Error fetching data with Axios:', error); } }; fetchDataWithAxios();
- : 응답 데이터를 JSON 형태로 자동 파싱해 주기 때문에, .data에 바로접근할 수 있다.
- Fetch
const fetchDataWithFetch = async () => { try { const response = await fetch('//url'); if (!response.ok) { throw new Error('Network response was not ok'); } const data = await response.json(); // JSON 파싱 필요 console.log(data); } catch (error) { console.error('Error fetching data with Fetch:', error); } }; fetchDataWithFetch();
- : 응답을 수동으로 .json() 메서드를 통해 JSON 파싱해야 한다.
3️⃣ 에러 핸들링
- Axios
import axios from 'axios'; const fetchDataWithAxios = async () => { try { const response = await axios.get('//url'); console.log(response.data); } catch (error) { // HTTP 상태 코드가 200대가 아니면 이곳에서 에러 처리 if (error.response) { // 서버가 응답을 했지만, 200대가 아닌 경우 console.error('Error Status:', error.response.status); console.error('Error Data:', error.response.data); } else { // 서버에 도달하지 못한 경우 console.error('Network Error:', error.message); } } }; fetchDataWithAxios();
- : HTTP 상태 코드가 200대가 아니면 자동으로 에러 처리해 주기 때문에 에러 처리가 간편하다.
- Fetch
const fetchDataWithFetch = async () => { try { const response = await fetch('//url'); // 성공 여부 확인을 위해 응답의 .ok 프로퍼티를 수동으로 체크 if (!response.ok) { throw new Error(`HTTP error! Status: ${response.status}`); } const data = await response.json(); console.log(data); } catch (error) { console.error('Fetch Error:', error.message); } }; fetchDataWithFetch();
- : HTTP 상태 코드에 따라 에러로 자동 처리되지 않으며, .ok 프로퍼티로 성공 여부를 체크해야 한다.
4️⃣ 취소 기능
- Axios
import axios from 'axios'; const source = axios.CancelToken.source(); const fetchDataWithAxios = async () => { try { const response = await axios.get('//url', { **cancelToken: source.token** }); console.log(response.data); } catch (error) { if (axios.isCancel(error)) { console.log('Request canceled:', error.message); } else { console.error('Error:', error.message); } } }; // 1초 후에 요청 취소 fetchDataWithAxios(); setTimeout(() => { source.cancel('Operation canceled by the user.'); }, 1000);
- : 요청 취소 기능이 있어, CancelToken을 사용하여 요청을 중단할 수 있다.
- Fetch
const controller = new AbortController(); const { signal } = controller; const fetchDataWithFetch = async () => { try { const response = await fetch('//url', { **signal** }); // 취소 신호 전달 const data = await response.json(); console.log(data); } catch (error) { if (error.name === 'AbortError') { console.log('Fetch request canceled'); } else { console.error('Fetch error:', error.message); } } }; // 1초 후에 요청 취소 fetchDataWithFetch(); setTimeout(() => { controller.abort(); console.log('Fetch request manually aborted'); }, 1000);
- : 기본적으로 취소 기능을 제공하지 않지만, AbortController를 사용하여 취소할 수 있다.
📌 Fetch와 Axios 에러 핸들링 딥다이브
💭 fetch와 axios의 에러핸들링 차이는 두 라이브러리의 설계철학에 기반한다.
✅ axios의 에러 처리 방식
: axios는 HTTP요청 후 HTTP 상태 코드가 200번대가 아닐 경우, 이를 실패로 간주하고 에러로 자동 처리한다. 따라서 try-catch블록이나, .catch() 에서 오류가 발생하면 바로 확인할 수 있다.
이렇게 자동화된 에러 처리 방식으로 개발자는 상태 코드 검사 로직을 추가할 필요가 없어 간편하며, 서버 오류나 클라이언트 오류도 코드에서 분기없이 간단히 처리할 수 있다.
🍎 설계철학
: axios는 “비정상적인 상태는 에러로 처리한다”는 철학을 바탕으로, HTTP 오류 코드를 자동으로 에러로 분류하여 통신 상태에 대한 예외 처리를 간단하게 만든다.
💻 예시코드
import axios from 'axios';
const fetchDataWithAxios = async () => {
try {
const response = await axios.get('//Url');
console.log('Data:', response.data);
} catch (error) {
if (error.response) {
// HTTP 상태 코드가 200대가 아닌 경우
console.log('Axios Error Status:', error.response.status);
console.log('Axios Error Data:', error.response.data);
} else {
// 네트워크 오류나 요청 실패 시
console.log('Network or Request Error:', error.message);
}
}
};
fetchDataWithAxios();
이 코드에서 error.response 가 있으면 이는 서버의 응답이 정상적이지 않다는 뜻이며, 네트워크 문제가 있을 경우 error.message가 제공된다.
✅ fetch의 에러 처리 방식
: fetch는 모든 HTTP응답을 성공으로 간주하고, HTTP 상태 코드에 관계없이 Promise가 성공적으로 완료되었다고 본다. 따라서 응답의 상태 코드가 200번대가 아닐 경우에도 .catch()가 자동으로 실행되지 않으며, 수동으로 .ok프로퍼티를 통해 상태 코드를 확인해야 한다.
이는 fetch가 단순히 데이터를 가져오는 함수로 설계되었기 때문에 모든 요청이 성공으로 완료된다고 보고, 에러 처리의 책임을 개발자에게 전가한 철학을 가지고 있기 때문이다.
🍎 설계철학
: fetch는 HTTP 상태와 에러를 구분하며, 통신의 성공 여부와 결과 데이터의 신뢰성 여부는 개발자가 판단하도록 설계되었다.
💻 예시코드
const fetchDataWithFetch = async () => {
try {
const response = await fetch('//url');
// 응답이 성공 상태인지 확인해야 함
if (!response.ok) {
throw new Error(`HTTP error! Status: ${response.status}`);
}
const data = await response.json();
console.log('Data:', data);
} catch (error) {
console.log('Fetch Error:', error.message);
}
};
fetchDataWithFetch();
여기서 response.ok 가 false 라면 직접 에러를 발생시켜야 하고, 에러가 .catch() 로 전달된다.
✅ 각기 다른 에러 처리 방식을 선택하는 이유와 설계 철학
axios의 철학은 더 직관적이고 신속한 에러 처리를 목표로 하며, 사용자가 HTTP 상태 코드를 따로 검사할 필요 없이 자동으로 처리하는 편리성을 제공한다. 이 접근 방식은 API 통신에서 간결한 코드와 에러 분류의 일관성을 제공하기 때문에, 서버 상태 코드에 따라 바로 오류를 처리할 수 있다.
fetch의 철학은 개발자가 요청의 모든 세부 사항을 수동으로 제어하도록 허용하고, 데이터 상태와 통신 성공여부를 구분하여 관리할 수 있도록 한다. fetch는 최대한 심플하고 보편적으로 설계되었으며, 사용자가 성공 여부나 에러 발생 기준을 커스터마이즈하도록 설계되었다.
🤔 데이터 상태와 통신 성공여부를 구분한다?
- 통신 성공 여부
- : 서버에서 응답이 오면 성공으로 간주하고 Promise를 완료 처리한다. 예를들어 HTTP코드가 404(페이지를 찾을 수 없음), 500(서버 오류)여도 네트워크 통신 자체가 성공했기 때문에 fetch는 이를 성공적인 응답으로 간주한다. 즉 .then으로 응답 받을 수 있다.
- 데이터 상태
- : fetch는 통신이 성공했다고 해서 그 결과가 유효한 데이터임을 보장하지 않는다. 서버의 응답 코드가 200번대가 아니라면 사실상 원하는 데이터가 없거나, 요청이 올바르게 처리되지 않는 상태이다. 이런 경우 response.ok를 통해 성공 상태를 확인하거나 상태 코드를 직접 검사하여 데이터가 유효한지 판단해야 한다. 개발자가 response.ok로 HTTP 상태를 수동으로 검사해서 데이터의 신뢰성을 확인해야 한다.
✅ 선택의 기준: 에러를 얼마나 자동으로 처리할 것인가?
: axios는 일관된 에러 처리가 필요하고 API 요청이 많은 경우 유리하다. 예를 들어, 오류 상태를 분기하는 코드가 많거나, 상태 코드에 따라 특정 처리를 해야하는 경우 axios의 자동화된 에러처리가 특히 유용하다.
반면, fetch는 데이터의 존재 여부만 검증하고 요청 성공 여부를 간단히 처리해야 하는 경우 유용하다. 특히 상태 코드에 따른 로직이 불필요한 프로젝트에서는 fetch의 단순한 설계가 효율적일 수 있다.
📌 Axios의 장점과 단점
장점 단점
- 코드 간결성 | - 파일 크기 |
- 에러 핸들링 | - 호환성 |
- 전역 설정 | |
- 요청 취소 | |
-인터셉터 지원 |
🍏 장점
- 코드 간결성
- : 데이터 파싱이나 요청 설정을 자동으로 처리해줘서 코드가 간결해진다.
- 에러 핸들링
- : 상태 코드가 실패일 때 자동 에러처리가 가능하다.
- 전역 설정
- : baseURL이나 헤더 등을 전역으로 설정할 수 있어 반복되는 코드를 줄일 수 있다.
- 요청 취소
- : CancelToken으로 요청 취소 기능을 제공한다.
- 인터셉터 지원
- : 요청 전후에 공통 작업을 수행할 수 있는 인터셉터 기능을 제공한다.
🍎 단점
- 파일 크기
- : Fetch는 브라우저에 내장되어 있지만 Axios는 외부 라이브러리로, 파일 크기가 커져 프로젝트 빌드 크기에 영향을 줄 수 있다.
- 호환성
- : 특정 환경에서만 작동하는 기능이 있을 수 있어, 네이티브 API 측면에서 떨어질 수 있다.
'4주차' 카테고리의 다른 글
Emotion CSS와 JSX Pragma (1) | 2024.11.21 |
---|---|
[React] 왜 TypeScript?? 그리고 interface VS type (0) | 2024.11.15 |
[4주차] AXIOS 알아보기 (0) | 2024.11.14 |
async/await 무엇일까? (0) | 2024.11.14 |
TypeScript의 interface는 설계도다! (0) | 2024.11.13 |