앞서 살펴보았던 http에 대해서 알아볼 때 서버와 클라이언트 간의 데이터 통신을 할 때
클라이언트가 리퀘스트를 보내면 서버가 여러 단계를 거쳐서 서버가 응답을 해준다는 것을 살펴보았습니다.
API를 통해 리퀘스트를 보내는 경우, 여러분은 fetch와 axios 어떤 것을 사용하시나요?
오늘은 둘을 비교 분석해보는 시간을 가져보겠습니다.

두 가지 HTTP Request에 대해서 간단하게 정리해보았는데,
실제 Request 코드를 보면서 차이점에 대해서 알아보도록 하겠습니다.
: API 서버의 등록된 데이터를 뽑아보자 !
async function getProduct(id) {
try {
const res = await fetch(
`https://panda-market-api-crud.vercel.app/products/${id}`
);
if (!res.ok) {
throw new Error(`HTTP error! ${res.status}`);
}
const data = await res.json();
return data;
} catch (error) {
console.log("Error!");
} finally {
console.log("Finished!");
}
}
1) fetch는 status가 404 에러나 다른 HTTP 에러 응답을 받았다고 해서 promise를 reject 하지 않기에 별도로 "if(!res.ok)"와 같이 에러를 처리할 수 있는 코드가 필요함
2) json 핸들링을 위해 데이터를 return시 별도 작업 필요
3) get method가 기본 지정이라 별도 옵션을 지정하지 않아도 됨
import axios from "axios";
const instance = axios.create({
baseURL: "https://panda-market-api-crud.vercel.app/",
timeout: 5000,
});
function getArticle(id) {
return instance
.get(`/articles/${id}`)
.then((res) => {
return res.data;
})
.catch((e) => {
if (e.response) {
console.log(e.response.status);
console.log(e.response.data);
} else {
console.log("ID 조회에 실패하였습니다.");
}
});
}
1) axios는 외장 모듈이기에 별도 설치 및 import 명령어 필요
2) 반복되는 URL은 instance 생성을 통해서 코드 단축 가능
3) 네트워크 응답 시간 Request timeout 설정 가능
4) get method가 기본값이라 옵션 설정하지 않아도 되지만, .get() 와 같이 별도의 함수를 제공하기에 명시적으로 사용
5) 가져온 데이터는 data 프로퍼티를 통해서 접근 가능(json 핸들링 내장)
6) 리퀘스트 실패 혹은 상태 코드가 실패(4XX, 5XX)를 나타내면 Promise가 reject 하기에 별도의 에러 코드 생략 가능
: 데이터 생성하기
async function createProduct(name, description, price, tags, images) {
try {
const res = await fetch(
"https://panda-market-api-crud.vercel.app/products",
{
method: "POST",
body: JSON.stringify({
name: name,
description: description,
price: price,
tags: tags || [],
images: images || [],
}),
headers: {
"Content-Type": "application/json",
},
}
);
if (!res.ok) {
throw new Error(`HTTP error! ${res.status}`);
}
const data = await res.json();
return data;
} catch (error) {
console.log("Error!");
} finally {
console.log("Finished!");
}
}
1) body 옵션을 통해서 데이터 전송
- 데이터 타입 : applcation/json
- 문자 변환 : JSON.stringify
function creatArticle(title, content, image) {
return instance
.post("/articles", {
title,
content,
image,
})
.then((res) => {
return res.data;
})
.catch((e) => {
if (e.response) {
console.log(e.response.status);
console.log(e.response.data);
} else {
console.log("작성에 실패하였습니다.");
}
});
}
1) 데이터 전송을 data 옵션 사용
2) 자동으로 JSON 문자로 변환
: 생성한 데이터 수정하기
async function patchProduct(id, patchData) {
try {
const res = await fetch(
`https://panda-market-api-crud.vercel.app/products/${id}`,
{
method: "PATCH",
body: JSON.stringify(patchData),
headers: {
"Content-Type": "application/json",
},
}
);
if (!res.ok) {
throw new Error(`HTTP error! ${res.status}`);
}
const data = await res.json();
return data;
} catch (error) {
console.log("Error!");
} finally {
console.log("Finished!");
}
}
function patchArticle(id, data) {
return instance
.patch(`/articles/${id}`, data)
.then((res) => {
return res.data;
})
.catch((e) => {
if (e.response) {
console.log(e.response.status);
console.log(e.response.data);
} else {
console.log("수정에 실패하였습니다.");
}
});
}
: 생성 후 수정한 데이터 삭제하기!
async function deleteProduct(id) {
try {
const res = await fetch(
`https://panda-market-api-crud.vercel.app/products/${id}`,
{
method: "DELETE",
headers: {
"Content-Type": "application/json",
},
}
);
if (!res.ok) {
throw new Error(`HTTP error! ${res.ststus}`);
}
const data = await res.json();
return data;
} catch (error) {
console.log("Error!");
} finally {
console.log("Finished!");
}
}
1) id로 삭제할 데이터를 찾으니, 추가 필요한 데이터가 없어서 body 생략
function deleteArticle(id) {
return instance
.delete(`/articles/${id}`)
.then((res) => {
return res.data;
})
.catch((e) => {
if (e.response) {
console.log(e.response.satus);
console.log(e.response.data);
} else {
console.log("삭제에 실패하였습니다.");
}
});
}
출처
https://www.heropy.dev/p/QOWqjV
https://tlsdnjs12.tistory.com/26
https://velog.io/@eunbinn/Axios-vs-Fetch