fetch와 axios 비교
웹 개발에서 데이터를 비동기적으로 가져오는 것은 매우 일반적인 작업이다. 이를 위해 주로 사용되는 두 가지 도구가 있는데, 바로 fetch와 axios이다. 참고로 이들은 구식 브라우저에서는 지원하지 않으므로 폴리필이 필요하다.Fetch 정의 :웹 브라우저 내장 API로, 네트워크 요청을 비동기적으로 처리하기 위해 만들어졌다. const res = await fetch(url); res.status; // response 코드 res.headers; // response 헤더 // response body await res.json(); // JSON 문자열을 파싱해서 자바스크립트 객체로 변환함. await res.text(); // 문자열을 그대로 가져옴.res.json() : 바디의 JSON 문자열을 파싱해서 자바스크립트 객체로 변환res.text() : 바디의 내용을 문자열로 그대로 가져옴.만약 body의 내용이 JSON이 아닌데 res.json으로 파싱하면 오류가 남. fetch() 옵션method (메소드)GET, POST, PATCH, DELETE지정하지 않으면 기본 값이 GETheaders (헤더)Content-TypeAuthorizationbody (바디)자바스크립트 객체는 그대로 전달할 수 없기 때문에 JSON 문자열로 바꿔줘야 함. 장점 :웹 표준:Fetch는 웹 표준으로, 모든 최신 브라우저에서 기본적으로 지원된다.웹 표준 API로서의 Fetch는 setTimeout, console 등과 함께 자주 사용된다. 단점 :추가 구현 필요:Fetch를 사용할 때는 axios와 비교하여 수동으로 구현해야 하는 기능들이 있다.예를 들어, 요청과 응답을 중간에 가로채어 처리하는 Interceptor 기능은 직접 작성해야 한다. // 요청을 보내기 전에 수행할 작업 const requestInterceptor = (url, options) => { console.log('Request Interceptor:', url, options); // 예: 인증 토큰 추가 const modifiedOptions = { ...options, headers: { ...options.headers, 'Authorization': 'Bearer YOUR_TOKEN' } }; return { url, options: modifiedOptions }; }; // 응답을 받은 후에 수행할 작업 const responseInterceptor = async (response) => { console.log('Response Interceptor:', response); if (!response.ok) { const errorData = await response.json(); throw new Error(`Error: ${response.status} - ${errorData.message}`); } return response.json(); }; const fetchWithInterceptors = async (url, options) => { const { url: interceptedUrl, options: interceptedOptions } = requestInterceptor(url, options); try { const response = await fetch(interceptedUrl, interceptedOptions); return await responseInterceptor(response); } catch (error) { // 에러 처리 console.error('Fetch Error:', error); throw error; } }; // 사용 예시 fetchWithInterceptors('https://api.example.com/data', { method: 'GET' }) .then(data => console.log('Data:', data)) .catch(error => console.error('Error:', error));응답값 파싱:Fetch는 기본적으로 응답값을 자동으로 파싱하지 않는다.응답을 JSON 형식으로 변환하려면 res.json() 메서드를 호출해야 한다. 이는 코드 작성 시 추가 단계를 필요로 한다.fetch('https://api.example.com/data') .then(response => response.json()) .then(data => console.log(data)) .catch(error => console.error('Error:', error));에러 핸들링: HTTP 오류 상태 코드(예: 404, 500)는 Fetch에서는 자동으로 에러로 처리되지 않는다.Fetch API에서는 HTTP 상태 코드가 200-299 범위가 아니어도 네트워크 요청이 성공하면 Promise를 반환한다. 따라서 상태 코드에 따라 별도로 오류를 처리해야한다. 이를 위해 res.status를 사용하여 각 상태 코드에 대한 처리를 세분화할 수 있다.export async function getColorSurvey(id) { const res = await fetch(`https://www./${id}`); if (!res.ok) { throw new Error('데이터를 불러오는데 실패했습니다.'); } const data = await res.json(); return data; }export async function getColorSurvey(id) { const res = await fetch(`https://www.example.com/${id}`); // 상태 코드에 따라 오류 메시지를 다르게 처리 if (!res.ok) { if (res.status >= 400 && res.status < 500) { throw new Error('클라이언트 오류가 발생했습니다. 요청을 다시 확인하세요.'); } else if (res.status >= 500) { throw new Error('서버 오류가 발생했습니다. 나중에 다시 시도하세요.'); } else { throw new Error('알 수 없는 오류가 발생했습니다.'); } } const data = await res.json(); return data; } axios 정의 :브라우저와 Node.js 환경 모두에서 동작하는 HTTP 클라이언트 라이브러리axios는 HTTP 메소드 이름과 동일한 메소드를 사용하고 리스폰스 바디를 data 프로퍼티로 접근할 수 있다. axios 옵션GET, DELETE RequestRequest body가 필요 없기 때문에 옵션을 두 번째 아규먼트로 받는다. POST, PATCH, PUTRequestRequest에 보낼 body 내용은 두 번째 아규먼트로 받고, 옵션을 세 번째 아규먼트로 받는다.별도의 파싱과정이 없이 JSON으로 변환된다. // Axios 모듈 가져오기 import axios from 'axios'; // GET 요청 (Request Body 없음) axios.get('https://api.example.com/data', { // 옵션 params: { id: 123 }, headers: { 'Authorization': 'Bearer token123' } }) .then(response => { console.log(response.data); }) .catch(error => { console.error('에러 발생:', error); }); // DELETE 요청 (Request Body 없음) axios.delete('https://api.example.com/data/123', { // 옵션 headers: { 'Authorization': 'Bearer token123' } }) .then(response => { console.log(response.data); }) .catch(error => { console.error('에러 발생:', error); });// POST 요청 (Request Body 있음) axios.post('https://api.example.com/data', { name: 'John Doe', age: 30 }, { // 옵션 headers: { 'Authorization': 'Bearer token123' } }) .then(response => { console.log(response.data); }) .catch(error => { console.error('에러 발생:', error); }); // PATCH 요청 (Request Body 있음) axios.patch('https://api.example.com/data/123', { age: 31 }, { // 옵션 headers: { 'Authorization': 'Bearer token123' } }) .then(response => { console.log(response.data); }) .catch(error => { console.error('에러 발생:', error); }); // PUT 요청 (Request Body 있음) axios.put('https://api.example.com/data/123', { name: 'Jane Doe', age: 25 }, { // 옵션 headers: { 'Authorization': 'Bearer token123' } }) .then(response => { console.log(response.data); }) .catch(error => { console.error('에러 발생:', error); }); axios 인스턴스리퀘스트마다 공통되는 부분이 있으면 axios.create()으로 인스턴스를 생성한다.해당 인스턴스로 리퀘스트를 보내면 된다.const axios = require('axios'); // Axios 인스턴스 생성 const instance = axios.create({ baseURL: 'https://api.example.com/', // 기본 URL 설정 timeout: 5000, // 타임아웃 설정 (밀리초) headers: { 'Authorization': 'Bearer token123' // 기본 헤더 설정 } });// GET 요청 예제 instance.get('/data') .then(response => { console.log(response.data); }) .catch(error => { console.error('에러 발생:', error); }); // POST 요청 예제 instance.post('/data', { name: 'John Doe', age: 30 }) .then(response => { console.log(response.data); }) .catch(error => { console.error('에러 발생:', error); });https://axios-http.com/docs/instance 참고 :Fetch() 함수는 원래 웹 브라우저에서만 사용할 수 있었으며, Node.js에서는 사용할 수 없었다.그러나 Node.js v17.5부터 실험적인 기능으로 Fetch가 도입되었고, 이에 따라 주의 메시지가 출력되었다.이후, Node.js v18.13부터는 이 기능이 안정화되어 더 이상 주의 메시지가 출력되지 않는다. 장점 :간편한 코드 작성 : 코드 작성이 간편하다.직관적인 문법 : 문법이 직관적이다.다양한 기능 : 인터셉터, 타임아웃, 요청 취소 등의 기능을 제공한다.에러 처리 용이 : catch 블록에서 에러 처리가 가능하다.자동 JSON 파싱 : 응답 데이터(res.data)는 자동으로 JSON으로 파싱된다.(텍스트로 파싱이 필요할 경우 res.text()를 사용하면 된다.)axios.get('https://api.example.com/data') .then(response => { console.log(response.data); // JSON 데이터, response.json() 불필요 }) .catch(error => { console.error('Error:', error); });단점 :번들 사이즈 증가 : axios는 많은 기능을 제공하지만 그만큼 번들 사이즈를 증가시킨다. 특히 번들 사이즈가 커지면 로딩 시간이 길어질 수 있다. axios의 기능 3개 :1) 인터셉터axios의 인터셉터는 요청과 응답을 가로채고 수정할 수 있는 기능이다. 이를 통해 전역적으로 요청과 응답을 처리하거나, 특정 상황에 맞게 헤더를 추가하거나 변경할 수 있다. 예를 들어, 모든 요청에 인증 토큰을 추가하거나, 응답 데이터를 특정 형식으로 변환하는 등의 작업을 수행할 수 있다. 모든 요청에 대해 인증 토큰 추가하기axios.interceptors.request.use(config => { const token = localStorage.getItem('token'); if (token) { config.headers.Authorization = `Bearer ${token}`; } return config; }, error => { return Promise.reject(error); }); 응답에 대한 에러 처리하기axios.interceptors.response.use(response => { // 응답이 성공인 경우 return response; }, error => { // 응답이 에러인 경우 if (error.response.status === 401) { // 인증 오류 처리 } else if (error.response.status === 404) { // 리소스를 찾을 수 없음 처리 } else { // 기타 오류 처리 } return Promise.reject(error); }); 요청 또는 응답에 대한 로깅axios.interceptors.request.use(config => { console.log('요청 시작:', config); return config; }); axios.interceptors.response.use(response => { console.log('응답 받음:', response); return response; }, error => { console.error('에러 발생:', error); return Promise.reject(error); }); 2) 타임아웃axios는 요청에 대한 응답을 기다리는 시간을 설정할 수 있는 타임아웃 기능을 제공한다.이를 사용하여 서버로의 요청에 대한 응답이 지연되는 경우, 일정 시간이 지난 후에 요청을 취소하고 에러를 발생시킬 수 있다.axios.get('/api/data', { timeout: 5000 }) .then(response => { // 성공적으로 데이터를 받았을 때의 처리 }) .catch(error => { // 타임아웃 또는 다른 에러 처리 }); 3) 요청 취소 기능axios는 요청을 취소하는 기능을 제공하여, 요청이 보내진 후에도 요청을 중단시킬 수 있다.이는 사용자가 요청을 취소하고 다른 작업을 수행할 때 유용하다.const source = axios.CancelToken.source(); axios.get('/api/data', { cancelToken: source.token }) .then(response => { // 성공적으로 데이터를 받았을 때의 처리 }) .catch(error => { if (axios.isCancel(error)) { // 요청이 취소된 경우 처리 } else { // 다른 에러 처리 } }); // 요청 취소 source.cancel('요청이 사용자에 의해 취소되었습니다.')