Skip to content

Commit

Permalink
Merge pull request #42 from Wannabe-Woowa-Article/soi-ha
Browse files Browse the repository at this point in the history
  • Loading branch information
llqqssttyy authored Aug 12, 2024
2 parents d8ac13a + 2b9eb76 commit bd5c675
Showing 1 changed file with 371 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,371 @@
## πŸ”— [Axios vs. Fetch API: Selecting the Right Tool for HTTP Requests](https://medium.com/@johnnyJK/axios-vs-fetch-api-selecting-the-right-tool-for-http-requests-ecb14e39e285)

### πŸ—“οΈ λ²ˆμ—­ λ‚ μ§œ: 2024.08.05

### 🧚 λ²ˆμ—­ν•œ 크루: μ†Œν•˜(μ΅œμ†Œμ—°)

---

<img width="500px" src="https://miro.medium.com/v2/resize:fit:1400/format:webp/1*quTpcb5i1NuOx235KQynOg.jpeg"/>

μ†Œν”„νŠΈμ›¨μ–΄ 개발 λΆ„μ•Όμ—μ„œλŠ” 웹을 톡해 원격 μ„œλ²„μ™€ μ›ν™œν•˜κ²Œ μƒν˜Έ μž‘μš©ν•˜κ³  데이터λ₯Ό κ΅ν™˜ν•˜λŠ” λŠ₯λ ₯이 맀우 μ€‘μš”ν•©λ‹ˆλ‹€. APIμ—μ„œ 데이터λ₯Ό κ°€μ Έμ˜€κ±°λ‚˜, CRUD μž‘μ—…μ„ μˆ˜ν–‰ν•˜κ±°λ‚˜, 기타 λ„€νŠΈμ›Œν¬ κ΄€λ ¨ μž‘μ—…μ„ μˆ˜ν–‰ν•˜λŠ” 경우 HTTP μš”μ²­μ„ λ§Œλ“œλŠ” κ²ƒμ˜ μ€‘μš”μ„±μ€ 아무리 강쑰해도 μ§€λ‚˜μΉ˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€. Fetch와 AxiosλΌλŠ” 두 개의 널리 μ‚¬μš©λ˜λŠ” JavaScript λΌμ΄λΈŒλŸ¬λ¦¬λŠ” HTTP μš”μ²­μ„ μ²˜λ¦¬ν•˜κ³ μž ν•˜λŠ” κ°œλ°œμžλ“€μ—κ²Œ 졜고의 선택이 λ˜μ—ˆμŠ΅λ‹ˆλ‹€.

이 κΈ°μ‚¬μ—μ„œλŠ” Axios와 Fetchλ₯Ό λΉ„κ΅ν•˜μ—¬ λ‹€μ–‘ν•œ μž‘μ—…μ„ μˆ˜ν–‰ν•˜λŠ” 방법을 μ‚΄νŽ΄λ³΄κ² μŠ΅λ‹ˆλ‹€. 이 글을 마칠 λ•Œμ―€μ΄λ©΄ 두 API에 λŒ€ν•΄ 더 잘 μ΄ν•΄ν•˜κ²Œ 될 κ²ƒμž…λ‹ˆλ‹€.

### AXIOS

AxiosλŠ” λ„€νŠΈμ›Œν¬ μš”μ²­μ„ λ§Œλ“œλŠ” 데 μ‚¬μš©λ˜λŠ” third-party HTTP ν΄λΌμ΄μ–ΈνŠΈ λΌμ΄λΈŒλŸ¬λ¦¬μž…λ‹ˆλ‹€. Promiseλ₯Ό 기반으둜 ν•˜λ©° μš”μ²­ 및 응닡을 μ²˜λ¦¬ν•˜κΈ° μœ„ν•œ κΉ”λ”ν•˜κ³  μΌκ΄€λœ APIλ₯Ό μ œκ³΅ν•©λ‹ˆλ‹€.

μ½˜ν…μΈ  배포 λ„€νŠΈμ›Œν¬(CDN) λ˜λŠ” νŒ¨ν‚€μ§€ κ΄€λ¦¬μž(예: npm)λ₯Ό μ‚¬μš©ν•˜μ—¬ ν”„λ‘œμ νŠΈμ— μΆ”κ°€ν•  수 μžˆμŠ΅λ‹ˆλ‹€. 핡심 κΈ°λŠ₯ 쀑 μΌλΆ€λŠ” λ‹€μŒκ³Ό κ°™μŠ΅λ‹ˆλ‹€:
λΈŒλΌμš°μ € λ‚΄μ—μ„œ XMLHttpRequests μˆ˜ν–‰, node.js ν™˜κ²½ λ‚΄μ—μ„œ http μš”μ²­ μˆ˜ν–‰, μš”μ²­ μ·¨μ†Œ, μš”μ²­ 및 응닡 κ°€λ‘œμ±„κΈ°

### FETCH

Axios와 λ§ˆμ°¬κ°€μ§€λ‘œ FetchλŠ” Promise 기반 HTTP ν΄λΌμ΄μ–ΈνŠΈμž…λ‹ˆλ‹€. λ‚΄μž₯ APIμ΄λ―€λ‘œ μ„€μΉ˜ν•˜κ±°λ‚˜ κ°€μ Έμ˜¬ ν•„μš”κ°€ μ—†μŠ΅λ‹ˆλ‹€. ν˜„λŒ€μ˜ λͺ¨λ“  λΈŒλΌμš°μ €μ—μ„œ μ‚¬μš©ν•  수 있으며 [caniuse](https://caniuse.com/fetch)μ—μ„œ 확인할 수 μžˆμŠ΅λ‹ˆλ‹€. λ˜ν•œ node.jsμ—μ„œλ„ μ‚¬μš©ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

이제 두 인기 μžˆλŠ” 라이브러리λ₯Ό μ΄ν•΄ν•˜κΈ° μœ„ν•΄ κΈ°λ³Έ ꡬ문, κΈ°λŠ₯ 및 μ‚¬μš© 사둀λ₯Ό 비ꡐ해 λ³΄κ² μŠ΅λ‹ˆλ‹€.

### 기본 ꡬ문

AxiosλŠ” μš”μ²­ λ§€κ°œλ³€μˆ˜(헀더, 데이터, μš”μ²­ λ©”μ„œλ“œ λ“±)λ₯Ό κ°„λ‹¨ν•˜κ²Œ ꡬ성할 수 μžˆλŠ” μ—°κ²° κ°€λŠ₯ν•œ APIλ₯Ό μ œκ³΅ν•˜μ—¬ HTTP μš”μ²­μ„ κ°„μ†Œν™”ν•©λ‹ˆλ‹€.

λ‹€μŒμ€ Axiosλ₯Ό μ‚¬μš©ν•˜μ—¬ μ‚¬μš©μž μ •μ˜ 헀더와 ν•¨κ»˜ URL에 [POST] μš”μ²­μ„ λ³΄λ‚΄λŠ” λ°©λ²•μž…λ‹ˆλ‹€. AxiosλŠ” 데이터λ₯Ό μžλ™μœΌλ‘œ JSON으둜 λ³€ν™˜ν•˜λ―€λ‘œ 직접 λ³€ν™˜ν•  ν•„μš”κ°€ μ—†μŠ΅λ‹ˆλ‹€.

```jsx
const axios = require('axios');

const url = 'https://jsonplaceholder.typicode.com/posts';
const data = {
title: 'Hello World',
body: 'This is a test post.',
userId: 1,
};

axios
.post(url, data, {
headers: {
Accept: 'application/json',
'Content-Type': 'application/json;charset=UTF-8',
},
})
.then(({ data }) => {
console.log('POST request successful. Response:', data);
})
.catch((error) => {
console.error('Error:', error);
});
```

ν•΄λ‹Ή μ½”λ“œλ₯Ό fetch API μ½”λ“œμ™€ 비ꡐ해 보면, μ •ν™•νžˆ λ™μΌν•œ κ²°κ³Όλ₯Ό 얻을 수 μžˆμŠ΅λ‹ˆλ‹€.

```jsx
const url = 'https://jsonplaceholder.typicode.com/todos';

const options = {
method: 'POST',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json;charset=UTF-8',
},
body: JSON.stringify({
title: 'Hello World',
body: 'This is a test post.',
userId: 1,
}),
};

fetch(url, options)
.then((response) => response.json())
.then((data) => {
console.log('POST request successful. Response:', data);
});
```

FetchλŠ” POST μš”μ²­μ— 데이터λ₯Ό λ³΄λ‚΄λŠ” 데 body 속성을 μ‚¬μš©ν•˜λŠ” 반면, AxiosλŠ” data 속성을 ν™œμš©ν•©λ‹ˆλ‹€. AxiosλŠ” μ„œλ²„μ˜ 응닡 데이터λ₯Ό μžλ™μœΌλ‘œ λ³€ν™˜ν•˜μ§€λ§Œ, Fetchλ₯Ό μ‚¬μš©ν•  λ•ŒλŠ” response.json() λ©”μ„œλ“œλ₯Ό ν˜ΈμΆœν•˜μ—¬ 데이터λ₯Ό JavaScript 객체둜 νŒŒμ‹±ν•΄μ•Ό ν•©λ‹ˆλ‹€. λ˜ν•œ AxiosλŠ” 데이터 응닡을 data 객체 내에 μ „λ‹¬ν•˜λŠ” 반면, FetchλŠ” μ΅œμ’… 데이터λ₯Ό μ–΄λ–€ λ³€μˆ˜μ—λ„ μ €μž₯ν•  수 μžˆλ„λ‘ ν•©λ‹ˆλ‹€.

### 응닡 및 였λ₯˜ 처리

FetchλŠ” λ‘œλ”© ν”„λ‘œμ„ΈμŠ€μ— λŒ€ν•œ μ •ν™•ν•œ μ œμ–΄λ₯Ό μ œκ³΅ν•˜μ§€λ§Œ 두 개의 약속을 μ²˜λ¦¬ν•΄μ•Ό ν•˜λ―€λ‘œ λ³΅μž‘μ„±μ΄ μΆ”κ°€λ©λ‹ˆλ‹€. λ˜ν•œ 응닡을 λ‹€λ£° λ•Œ FetchλŠ” .json() λ©”μ„œλ“œλ₯Ό μ‚¬μš©ν•˜μ—¬ JSON 데이터λ₯Ό νŒŒμ‹±ν•΄μ•Ό ν•©λ‹ˆλ‹€. 그런 λ‹€μŒ κ²€μƒ‰λœ μ΅œμ’… λ°μ΄ν„°λŠ” μ–΄λ–€ λ³€μˆ˜μ—λ„ μ €μž₯ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

HTTP 응닡 였λ₯˜μ˜ 경우 FetchλŠ” μžλ™μœΌλ‘œ 였λ₯˜λ₯Ό λ˜μ§€μ§€ μ•ŠμŠ΅λ‹ˆλ‹€. λŒ€μ‹  μ„œλ²„μ—μ„œ 였λ₯˜ μƒνƒœ μ½”λ“œ(예: 404 Not found)λ₯Ό λ°˜ν™˜ν•˜λ”λΌλ„ 응닡을 μ„±κ³΅ν•œ κ²ƒμœΌλ‘œ κ°„μ£Όν•©λ‹ˆλ‹€.

Fetchμ—μ„œ HTTP 였λ₯˜λ₯Ό λͺ…μ‹œμ μœΌλ‘œ μ²˜λ¦¬ν•˜λ €λ©΄ κ°œλ°œμžλŠ” `.then()` 블둝 λ‚΄μ—μ„œ 쑰건문을 μ‚¬μš©ν•˜μ—¬ `response.ok` 속성을 확인해야 ν•©λ‹ˆλ‹€. `response.ok`κ°€ false이면 μ„œλ²„κ°€ 였λ₯˜ μƒνƒœ μ½”λ“œλ‘œ μ‘λ‹΅ν–ˆμŒμ„ μ˜λ―Έν•˜λ―€λ‘œ κ°œλ°œμžλŠ” ν•΄λ‹Ή 였λ₯˜λ₯Ό 적절히 μ²˜λ¦¬ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

λ‹€μŒμ€ Fetchλ₯Ό μ‚¬μš©ν•œ [GET] μš”μ²­μž…λ‹ˆλ‹€:

```jsx
fetch('https://jsonplaceholder.typicode.com/todos')
.then((response) => {
if (!response.ok) {
throw Error(`HTTP error: ${response.status}`);
}
return response.json();
})
.then((data) => {
console.log('Data received:', data);
})
.catch((error) => {
console.error('Error message:', error.message);
});
```

λ°˜λ©΄μ— AxiosλŠ” data 속성에 직접 μ•‘μ„ΈμŠ€ν•  수 있게 ν•˜μ—¬ 응닡 처리λ₯Ό κ°„μ†Œν™”ν•©λ‹ˆλ‹€. 200-299 λ²”μœ„(성곡적인 응닡)λ₯Ό λ²—μ–΄λ‚œ 응닡은 μžλ™μœΌλ‘œ κ±°λΆ€ν•©λ‹ˆλ‹€. `.catch()` 블둝을 μ‚¬μš©ν•˜λ©΄ 응닡을 λ°›μ•˜λŠ”μ§€, λ°›μ•˜λ‹€λ©΄ μƒνƒœ μ½”λ“œκ°€ 무엇인지 λ“± 였λ₯˜μ— λŒ€ν•œ 정보λ₯Ό 얻을 수 μžˆμŠ΅λ‹ˆλ‹€. μ΄λŠ” μ‹€νŒ¨ν•œ 응닡도 ν•΄κ²°λ˜λŠ” fetch와 λŒ€μ‘°λ©λ‹ˆλ‹€.

λ‹€μŒμ€ Axiosλ₯Ό μ‚¬μš©ν•œ [GET] μš”μ²­μž…λ‹ˆλ‹€:

```jsx
const axios = require('axios');

axios
.get('https://jsonplaceholder.typicode.com/todos')
.then((response) => {
console.log('Data received:', response.data);
})
.catch((error) => {
if (error.response) {
console.error(`HTTP error: ${error.response.status}`);
} else if (error.request) {
console.error('Request error: No response received');
} else {
console.error('Error:', error.message);
}
});
```

AxiosλŠ” μžλ™μœΌλ‘œ μ‹€νŒ¨ν•œ 응닡에 λŒ€ν•΄ 였λ₯˜λ₯Ό λ°œμƒμ‹œν‚€λ―€λ‘œ, 였λ₯˜ 처리λ₯Ό κ°„μ†Œν™”ν•˜κ³  κ°œλ°œμžκ°€ 각 μ‘λ‹΅μ˜ 성곡 λ˜λŠ” μ‹€νŒ¨λ₯Ό μˆ˜λ™μœΌλ‘œ ν™•μΈν•˜μ§€ μ•Šκ³ λ„ μ μ ˆν•œ 였λ₯˜ 처리 λ‘œμ§μ„ κ΅¬ν˜„ν•˜λŠ” 데 집쀑할 수 μžˆλ„λ‘ ν•©λ‹ˆλ‹€.

### HTTP μš”μ²­ 및 응닡 κ°€λ‘œμ±„κΈ°(Intercepting)

Axios의 μ£Όμš” κΈ°λŠ₯ 쀑 ν•˜λ‚˜λŠ” HTTP μš”μ²­μ„ μΈν„°μ…‰νŠΈν•  수 μžˆλ‹€λŠ” κ²ƒμž…λ‹ˆλ‹€. HTTP μΈν„°μ…‰ν„°λŠ” μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ—μ„œ μ„œλ²„λ‘œ λ˜λŠ” κ·Έ λ°˜λŒ€λ‘œ HTTP μš”μ²­μ„ κ²€μ‚¬ν•˜κ±°λ‚˜ λ³€κ²½ν•΄μ•Ό ν•  λ•Œ μœ μš©ν•©λ‹ˆλ‹€. λ‘œκΉ…, 인증 λ˜λŠ” μ‹€νŒ¨ν•œ HTTP μš”μ²­μ„ λ‹€μ‹œ μ‹œλ„ν•˜λŠ” 것과 같은 λ‹€μ–‘ν•œ μž‘μ—…μ— ν•„μˆ˜μ μž…λ‹ˆλ‹€.

인터셉터λ₯Ό μ‚¬μš©ν•˜λ©΄ 각 HTTP μš”μ²­μ— λŒ€ν•΄ λ³„λ„μ˜ μ½”λ“œλ₯Ό μž‘μ„±ν•  ν•„μš”κ°€ μ—†μŠ΅λ‹ˆλ‹€. HTTP μΈν„°μ…‰ν„°λŠ” μš”μ²­ 및 응닡을 μ²˜λ¦¬ν•˜λŠ” 방법에 λŒ€ν•œ μ „μ—­ μ „λž΅μ„ μ„€μ •ν•˜κ³ μž ν•  λ•Œ μœ μš©ν•©λ‹ˆλ‹€.

λ‹€μŒμ€ Axiosλ₯Ό μ‚¬μš©ν•˜μ—¬ HTTP μš”μ²­μ„ μΈν„°μ…‰νŠΈν•˜λŠ” λ°©λ²•μž…λ‹ˆλ‹€:

```jsx
const axios = require('axios');

// 인터셉터 μš”μ²­ 등둝
axios.interceptors.request.use((config) => {
// HTTP μš”μ²­μ΄ μ „μ†‘λ˜κΈ° 전에 λ©”μ‹œμ§€λ₯Ό κΈ°λ‘ν•©λ‹ˆλ‹€.
console.log('Request was sent');
return config;
});

// GET μš”μ²­ 전솑
axios
.get('https://jsonplaceholder.typicode.com/todos')
.then(({ data }) => {
console.log('Data received:', data);
})
.catch((error) => {
console.error('Error:', error.message);
});
```

이 μ½”λ“œμ—μ„œλŠ” `axios.interceptors.request.use()` λ©”μ„œλ“œλ₯Ό μ‚¬μš©ν•˜μ—¬ HTTP μš”μ²­μ΄ μ „μ†‘λ˜κΈ° 전에 μ‹€ν–‰ν•  μ½”λ“œλ₯Ό μ •μ˜ν•©λ‹ˆλ‹€.

λ˜ν•œ `axios.interceptors.response.use()`λ₯Ό μ‚¬μš©ν•˜μ—¬ μ„œλ²„μ˜ 응닡을 인터셉터할 μˆ˜λ„ μžˆμŠ΅λ‹ˆλ‹€. 예λ₯Ό λ“€μ–΄ λ„€νŠΈμ›Œν¬ 였λ₯˜κ°€ λ°œμƒν•œ 경우 응닡 인터셉터λ₯Ό μ‚¬μš©ν•˜μ—¬ λ™μΌν•œ μš”μ²­μ„ λ‹€μ‹œ μ‹œλ„ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

기본적으둜 fetch()λŠ” μš”μ²­μ„ μΈν„°μ…‰νŠΈν•  방법을 μ œκ³΅ν•˜μ§€ μ•Šμ§€λ§Œ, μš°νšŒμ±…μ„ μ°ΎλŠ” 것은 어렡지 μ•ŠμŠ΅λ‹ˆλ‹€. μ „μ—­ fetch() λ©”μ„œλ“œλ₯Ό μž¬μ •μ˜ν•˜κ³  λ‹€μŒκ³Ό 같이 인터셉터λ₯Ό μ •μ˜ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

λ‹€μŒμ€ Fetchλ₯Ό μ‚¬μš©ν•˜μ—¬ HTTP μš”μ²­μ„ μΈν„°μ…‰νŠΈν•˜λŠ” λ°©λ²•μž…λ‹ˆλ‹€.

```jsx
fetch = ((originalFetch) => {
return (...arguments) => {
return originalFetch.apply(this, arguments).then((response) => {
if (!response.ok) {
throw new Error(`HTTP error: ${response.status}`);
}
console.log('Request was sent');
return response;
});
};
})(fetch);

fetch('https://jsonplaceholder.typicode.com/todos')
.then((response) => response.json())
.then((data) => {
console.log('Data received:', data);
})
.catch((error) => {
console.error('Error:', error.message);
});
```

FetchλŠ” Axios에 λΉ„ν•΄ 더 λ§Žμ€ λ³΄μΌλŸ¬ν”Œλ ˆμ΄νŠΈ μ½”λ“œλ₯Ό κ°€μ§€λŠ” κ²½ν–₯이 μžˆμŠ΅λ‹ˆλ‹€. ν•˜μ§€λ§Œ 선택은 μ‚¬μš© 사둀와 개인적인 ν•„μš”μ— 따라 이루어져야 ν•©λ‹ˆλ‹€.

### 응닡 μ‹œκ°„ 초과

응닡 μ‹œκ°„ μ΄ˆκ³ΌλŠ” Fetch와 Axiosλ₯Ό 비ꡐ할 λ•Œ 또 λ‹€λ₯Έ μ€‘μš”ν•œ μ˜μ—­μž…λ‹ˆλ‹€. 응닡 μ‹œκ°„ μ΄ˆκ³ΌλŠ” ν΄λΌμ΄μ–ΈνŠΈκ°€ μ„œλ²„μ˜ 응닡을 κΈ°λ‹€λ¦¬λŠ” μ‹œκ°„μœΌλ‘œ, 이 μ‹œκ°„μ΄ μ§€λ‚˜λ©΄ μš”μ²­μ΄ μ‹€νŒ¨ν•œ κ²ƒμœΌλ‘œ κ°„μ£Όν•©λ‹ˆλ‹€.

Axiosμ—μ„œ μ‹œκ°„μ„ μ„€μ •ν•˜λŠ” 간결함은 일뢀 κ°œλ°œμžκ°€ Fetch보닀 Axiosλ₯Ό μ„ ν˜Έν•˜λŠ” 이유 쀑 ν•˜λ‚˜μž…λ‹ˆλ‹€. Axiosμ—μ„œλŠ” config 객체의 선택적 timeout 속성을 μ‚¬μš©ν•˜μ—¬ μš”μ²­μ΄ μ€‘λ‹¨λ˜κΈ° 전에 λ°€λ¦¬μ΄ˆ λ‹¨μœ„λ‘œ μ‹œκ°„μ„ μ„€μ •ν•  수 μžˆμŠ΅λ‹ˆλ‹€. 이 직관적인 μ ‘κ·Ό 방식은 κ°œλ°œμžκ°€ μš”μ²­ ꡬ성 λ‚΄μ—μ„œ 직접 μ‹œκ°„ 초과 기간을 μ •μ˜ν•  수 있게 ν•˜μ—¬ 더 큰 μ œμ–΄μ™€ κ΅¬ν˜„ μš©μ΄μ„±μ„ μ œκ³΅ν•©λ‹ˆλ‹€.

λ‹€μŒμ€ Axiosλ₯Ό μ‚¬μš©ν•˜μ—¬ μ§€μ •λœ μ‹œκ°„ μ œν•œμ΄ μžˆλŠ” [GET] μš”μ²­μž…λ‹ˆλ‹€.

```jsx
const axios = require('axios');

// νƒ€μž„μ•„μ›ƒ μ‹œκ°„μ„ λ°€λ¦¬μ΄ˆ λ‹¨μœ„λ‘œ μ •μ˜ν•©λ‹ˆλ‹€.
const timeout = 5000; // 5초

// νƒ€μž„μ•„μ›ƒ 속성이 μžˆλŠ” config 객체λ₯Ό μƒμ„±ν•©λ‹ˆλ‹€.
const config = {
timeout: timeout,
};

// μ§€μ •λœ νƒ€μž„μ•„μ›ƒμœΌλ‘œ GET μš”μ²­μ„ λ³΄λƒ…λ‹ˆλ‹€.
axios
.get('https://jsonplaceholder.typicode.com/todos', config)
.then((response) => {
console.log('Data received:', response.data);
})
.catch((error) => {
console.error('Error fetching data:', error.message);
});
```

Axiosλ₯Ό μ‚¬μš©ν•˜μ—¬ GET μš”μ²­μ„ 보내고 있으며, 두 번째 인수둜 config 객체λ₯Ό μ „λ‹¬ν•˜μ—¬ μ‹œκ°„ μ œν•œμ„ μ§€μ •ν•˜κ³  μžˆμŠ΅λ‹ˆλ‹€. μš”μ²­μ΄ μ„±κ³΅ν•˜λ©΄ μˆ˜μ‹ ν•œ 데이터가 μ½˜μ†”μ— λ‘œκ·Έλ©λ‹ˆλ‹€. μš”μ²­ 쀑에 였λ₯˜κ°€ λ°œμƒν•˜κ±°λ‚˜ μ‹œκ°„μ΄ 초과되면 였λ₯˜ λ©”μ‹œμ§€κ°€ μ½˜μ†”μ— λ‘œκ·Έλ©λ‹ˆλ‹€.

FetchλŠ” AbortController μΈν„°νŽ˜μ΄μŠ€λ₯Ό 톡해 μœ μ‚¬ν•œ κΈ°λŠ₯을 μ œκ³΅ν•˜μ§€λ§Œ Axios λ²„μ „λ§ŒνΌ μ§κ΄€μ μ΄μ§€λŠ” μ•ŠμŠ΅λ‹ˆλ‹€.

λ‹€μŒμ€ Fetchλ₯Ό μ‚¬μš©ν•˜μ—¬ HTTP μš”μ²­μ„ μΈν„°μ…‰νŠΈν•˜λŠ” λ°©λ²•μž…λ‹ˆλ‹€.

```jsx
const timeout = 5000; // 5초
// AbortController μΈμŠ€ν„΄μŠ€λ₯Ό μƒμ„±ν•©λ‹ˆλ‹€.
const controller = new AbortController();
const signal = controller.signal;

// μ§€μ •λœ νƒ€μž„μ•„μ›ƒ 후에 fetch μš”μ²­μ„ μ€‘λ‹¨ν•˜κΈ° μœ„ν•΄ setTimeout ν•¨μˆ˜λ₯Ό μ„€μ •ν•©λ‹ˆλ‹€.
const timeoutId = setTimeout(() => {
controller.abort();
}, timeout);

// μ§€μ •λœ URLκ³Ό μ‹ ν˜Έλ‘œ fetch μš”μ²­μ„ λ³΄λƒ…λ‹ˆλ‹€.
fetch('https://jsonplaceholder.typicode.com/todos', { signal })
.then((response) => {
if (!response.ok) {
throw new Error('Network response was not ok');
}
return response.json();
})
.then((data) => {
console.log('Data received:', data);
})
.catch((error) => {
// 였λ₯˜κ°€ μš”μ²­μ΄ μ€‘λ‹¨λœ 것 λ•Œλ¬ΈμΈμ§€ ν™•μΈν•©λ‹ˆλ‹€.
if (error.name === 'AbortError') {
console.error('Request timed out');
} else {
console.error('Error fetching data:', error.message);
}
})
.finally(() => {
// μš”μ²­μ΄ μ™„λ£Œλœ 후에 νƒ€μž„μ•„μ›ƒμ΄ λ°œμƒν•˜μ§€ μ•Šλ„λ‘ νƒ€μž„μ•„μ›ƒμ„ ν•΄μ œν•©λ‹ˆλ‹€.
clearTimeout(timeoutId);
});
```

5초 νƒ€μž„μ•„μ›ƒμ΄ fetch μš”μ²­μ— μ„€μ •λ˜λ©°, 이 μ œν•œ μ‹œκ°„μ„ μ΄ˆκ³Όν•  경우 μš”μ²­μ„ μ·¨μ†Œν•˜κΈ° μœ„ν•΄ `AbortController`κ°€ μƒμ„±λ©λ‹ˆλ‹€. `setTimeout`을 μ‚¬μš©ν•˜μ—¬ 이 기간이 μ§€λ‚˜λ©΄ μš”μ²­μ„ μ€‘λ‹¨μ‹œν‚€λŠ” 타이머가 μ‹œμž‘λ©λ‹ˆλ‹€. 그런 λ‹€μŒ fetch μš”μ²­μ΄ μ „μ†‘λ˜λ©°, 쀑단 μ‹ ν˜Έκ°€ ν¬ν•¨λ©λ‹ˆλ‹€. 응닡이 λ„μ°©ν•˜λ©΄ 성곡 μ—¬λΆ€λ₯Ό ν™•μΈν•˜κ³  데이터λ₯Ό νŒŒμ‹±ν•©λ‹ˆλ‹€. `timeouts`κ³Ό 같은 였λ₯˜λŠ” μ μ ˆν•˜κ²Œ μ²˜λ¦¬λ©λ‹ˆλ‹€. λ§ˆμ§€λ§‰μœΌλ‘œ, μš”μ²­μ΄ μ™„λ£Œλœ ν›„ λΆˆν•„μš”ν•œ 지연을 ν”Όν•˜κΈ° μœ„ν•΄ νƒ€μž„μ•„μ›ƒμ΄ ν•΄μ œλ©λ‹ˆλ‹€.

### λ™μ‹œ μš”μ²­

Fetch와 Axiosλ₯Ό 비ꡐ할 λ•Œ 또 λ‹€λ₯Έ μ€‘μš”ν•œ μ˜μ—­μ€ λ™μ‹œ μš”μ²­ λ˜λŠ” μ—¬λŸ¬ μš”μ²­μ„ λ™μ‹œμ— ν•  수 μžˆλŠ” κΈ°λŠ₯μž…λ‹ˆλ‹€. 이 κΈ°λŠ₯은 μ„±λŠ₯κ³Ό λ°˜μ‘μ„±μ΄ μ€‘μš”ν•œ μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ—μ„œ 특히 μ€‘μš”ν•©λ‹ˆλ‹€.

AxiosλŠ” `axios.all()` λ©”μ„œλ“œλ₯Ό μ œκ³΅ν•˜μ—¬ μ—¬λŸ¬ μš”μ²­μ„ λ™μ‹œμ— ν•  수 μžˆμŠ΅λ‹ˆλ‹€. 이 λ©”μ„œλ“œμ— μš”μ²­ 배열을 μ „λ‹¬ν•œ ν›„ `axios.spread()`λ₯Ό μ‚¬μš©ν•˜μ—¬ 응닡을 κ°œλ³„ 인수둜 펼칠 수 μžˆμŠ΅λ‹ˆλ‹€. 이λ₯Ό 톡해 각 응닡을 κ°œλ³„μ μœΌλ‘œ μ²˜λ¦¬ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

λ‹€μŒμ€ Axiosλ₯Ό μ‚¬μš©ν•˜μ—¬ λ™μ‹œμ— HTTP μš”μ²­μ„ λ³΄λ‚΄λŠ” λ°©λ²•μž…λ‹ˆλ‹€:

```jsx
const axios = require('axios');

// μš”μ²­μ˜ κΈ°λ³Έ URL μ •μ˜
const baseURL = 'https://jsonplaceholder.typicode.com/todos';

// μš”μ²­μ„ μœ„ν•œ URL μ •μ˜
const urls = [`${baseURL}/1`, `${baseURL}/2`, `${baseURL}/3`];

// Axios μš”μ²­ ν”„λΌλ―ΈμŠ€ λ°°μ—΄ 생성
const axiosRequests = urls.map((url) => axios.get(url));

// `axios.all()`을 μ‚¬μš©ν•˜μ—¬ μ—¬λŸ¬ μš”μ²­μ„ λ™μ‹œμ— 전솑
axios
.all(axiosRequests)
.then(
axios.spread((...responses) => {
// λͺ¨λ“  μš”μ²­μ˜ 응닡 처리
responses.forEach((response, index) => {
console.log(`Response from ${urls[index]}:`, response.data);
});
})
)
.catch((error) => {
console.error('Error fetching data:', error.message);
});
```

Fetchλ₯Ό μ‚¬μš©ν•˜μ—¬ λ™μΌν•œ κ²°κ³Όλ₯Ό μ–»κΈ° μœ„ν•΄μ„œλŠ” λ‚΄μž₯된 `Promise.all()` λ©”μ„œλ“œμ— λͺ¨λ“  fetch μš”μ²­μ„ λ°°μ—΄λ‘œ 전달해야 ν•©λ‹ˆλ‹€. 그런 λ‹€μŒ async ν•¨μˆ˜λ₯Ό μ‚¬μš©ν•˜μ—¬ 응닡을 μ²˜λ¦¬ν•©λ‹ˆλ‹€.

λ‹€μŒμ€ Fetchλ₯Ό μ‚¬μš©ν•˜μ—¬ λ™μ‹œμ— HTTP μš”μ²­μ„ λ³΄λ‚΄λŠ” λ°©λ²•μž…λ‹ˆλ‹€:

```jsx
// μš”μ²­ν•  base URL μ •μ˜
const baseURL = 'https://jsonplaceholder.typicode.com/todos';

// μš”μ²­ν•  URLs μ •μ˜
const urls = [`${baseURL}/1`, `${baseURL}/2`, `${baseURL}/3`];

// fetch μš”μ²­μ˜ ν”„λ‘œλ―ΈμŠ€λ₯Ό μ €μž₯ν•  λ°°μ—΄ 생성
const fetchRequests = urls.map((url) => fetch(url));

// `Promise.all()`을 μ‚¬μš©ν•˜μ—¬ μ—¬λŸ¬ μš”μ²­μ„ λ™μ‹œμ— 보냄
Promise.all(fetchRequests)
.then((responses) => {
// λͺ¨λ“  μš”μ²­μ˜ 응닡을 처리
responses.forEach((response, index) => {
if (!response.ok) {
throw new Error(`Request ${urls[index]} failed with status ${response.status}`);
}
response.json().then((data) => {
console.log(`Response from ${urls[index]}:`, data);
});
});
})
.catch((error) => {
console.error('Error fetching data:', error.message);
});
```

이 μ ‘κ·Ό 방식은 μ‹€ν–‰ κ°€λŠ₯ν•˜μ§€λ§Œ, 비동기 ν”„λ‘œκ·Έλž˜λ° κ°œλ…μ— μ΅μˆ™ν•˜μ§€ μ•Šμ€ κ°œλ°œμžλ“€μ—κ²ŒλŠ” 좔가적인 λ³΅μž‘μ„±κ³Ό μ˜€λ²„ν—€λ“œλ₯Ό μ΄ˆλž˜ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

### ν•˜μœ„ ν˜Έν™˜μ„±

ν•˜μœ„ ν˜Έν™˜μ„±μ€ μ†Œν”„νŠΈμ›¨μ–΄ μ‹œμŠ€ν…œμ΄λ‚˜ μ œν’ˆμ΄ μ’…μ†μ„±μ˜ 이전 버전과 ν•¨κ»˜ μ‚¬μš©λ˜κ±°λ‚˜ 이전 ν™˜κ²½μ—μ„œ μ‚¬μš©λ  λ•Œμ—λ„ μ˜¬λ°”λ₯΄κ²Œ λ˜λŠ” 효과적으둜 μž‘λ™ν•  수 μžˆλŠ” λŠ₯λ ₯을 λ§ν•©λ‹ˆλ‹€.

AxiosλŠ” 기본적으둜 더 λ‚˜μ€ ν•˜μœ„ ν˜Έν™˜μ„±μ„ μ œκ³΅ν•˜λ©°, 이전 μ‹œμŠ€ν…œμ΄λ‚˜ μ½”λ“œλ² μ΄μŠ€μ™€μ˜ ν˜Έν™˜μ„±μ„ μš©μ΄ν•˜κ²Œ ν•˜λŠ” μΆ”κ°€ κΈ°λŠ₯을 μ œκ³΅ν•©λ‹ˆλ‹€. Axios의 μ£Όμš” μž₯점 쀑 ν•˜λ‚˜λŠ” XMLHttpRequestλ₯Ό 기반으둜 ν•˜μ—¬ IE11κ³Ό 같은 였래된 λΈŒλΌμš°μ €λ₯Ό ν¬ν•¨ν•œ κ΄‘λ²”μœ„ν•œ λΈŒλΌμš°μ €λ₯Ό μ§€μ›ν•œλ‹€λŠ” κ²ƒμž…λ‹ˆλ‹€.

λ°˜λ©΄μ— FetchλŠ” Chrome, Firefox, Edge, Safari와 같은 ν˜„λŒ€ λΈŒλΌμš°μ €λ₯Ό 주둜 λŒ€μƒμœΌλ‘œ ν•˜λŠ” 더 μ œν•œλœ λΈŒλΌμš°μ € 지원을 μ œκ³΅ν•©λ‹ˆλ‹€. Fetch의 κΈ°λŠ₯이 μ§€μ›λ˜μ§€ μ•ŠλŠ” λΈŒλΌμš°μ €μ—μ„œ ν”„λ‘œμ νŠΈλ₯Ό 진행해야 ν•˜λŠ” 경우 'whatwg-fetch'와 같은 polyfill을 ν†΅ν•©ν•˜μ—¬ 격차λ₯Ό ν•΄μ†Œν•  수 μžˆμŠ΅λ‹ˆλ‹€. 이 폴리필은 Fetch 지원을 였래된 λΈŒλΌμš°μ €λ‘œ ν™•μž₯ν•˜μ—¬ ν˜Έν™˜μ„±μ„ 보μž₯ν•©λ‹ˆλ‹€.

μ‚¬μš©ν•˜λ €λ©΄ npm λͺ…령을 μ‚¬μš©ν•˜μ—¬ μ„€μΉ˜ν•  수 μžˆμŠ΅λ‹ˆλ‹€:

```bash
npm install whatwg-fetch - save
```

κ·Έλ‹€μŒμ—λŠ” λ‹€μŒκ³Ό 같이 μš”μ²­μ„ 보낼 수 μžˆμŠ΅λ‹ˆλ‹€:

```jsx
import 'whatwg-fetch'

window.fetch(…)
```

일뢀 였래된 λΈŒλΌμš°μ €μ—μ„œλŠ” promise polyfill이 ν•„μš”ν•  μˆ˜λ„ μžˆλ‹€λŠ” 점을 μœ μ˜ν•΄ μ£Όμ„Έμš”.

### κ²°λ‘ 

AxiosλŠ” 간결함, 견고함, κ΄‘λ²”μœ„ν•œ λΈŒλΌμš°μ € μ§€μ›μœΌλ‘œ 인해 였래된 λΈŒλΌμš°μ €μ™€μ˜ ν•˜μœ„ ν˜Έν™˜μ„±μ΄ ν•„μš”ν•œ ν”„λ‘œμ νŠΈμ— 이상적인 μ„ νƒμž…λ‹ˆλ‹€. λ°˜λ©΄μ— FetchλŠ” 슀트리밍 κΈ°λŠ₯κ³Ό λ‹€λ₯Έ μ›Ή ν”Œλž«νΌ API와 μ›ν™œν•˜κ²Œ μž‘μ—…ν•  수 μžˆλŠ” κΈ°λŠ₯을 μ§€μ›ν•˜λŠ” λΈŒλΌμš°μ €μ— 직접 λ‚΄μž₯된 보닀 λ„€μ΄ν‹°λΈŒν•œ μ ‘κ·Ό 방식을 μ œκ³΅ν•©λ‹ˆλ‹€.

Axios와 Fetch μ€‘μ—μ„œ 선택할 λ•Œ κ°œλ°œμžλŠ” μ‚¬μš© νŽΈμ˜μ„±, μ„±λŠ₯ 고렀사항, λΈŒλΌμš°μ € ν˜Έν™˜μ„± 및 ν•„μš”ν•œ μΆ”κ°€ κΈ°λŠ₯ λ“± ν”„λ‘œμ νŠΈ μš”κ΅¬ 사항을 μ‹ μ€‘ν•˜κ²Œ 평가해야 ν•©λ‹ˆλ‹€.

0 comments on commit bd5c675

Please sign in to comment.