axios.get("http://localhost:4000/todos");
axios.post("http://localhost:4000/todos", todo);
axios.delete(`http://localhost:4000/todos/${todoId}`);
이렇게 호출하는 부분이 우리의 리액트 앱에 300개 정도 존재한다고 가정해보자.
서버가 변경되면 모두 찾아서 변경해줘야 하므로 엄청난 인적 리소스가 낭비된다.
만약 콘솔로그로 응답값, 오류 등을 출력해봤다.
이것도 다 수정해줘야겠지?
console.log('요청 시작합니다...!');
axios interceptor는 이름에서 알 수 있듯 다음 두 상황에서 흐름을 가로채서 어떠한 코드 상의 관여를 할 수 있게 한다.
반복적으로 수행하는 것들을
요청(request)이 처리되기 전( = http request가 서버에 전달되기 전)
응답(response)의 then(=성공) 또는 catch(=실패)가 처리되기 전에
가로채서 어떤 역할을 하는 것이다.

따라서, 우리가 위에서 가정했던 상황들을 포함하여 요청 및 응답시에 필요한 작업들을 한꺼번에 처리할 수 있다.
const data = axios.get("http://localhost:4000/");
방법으로 데이터 통신을 해왔어요. axios를 썼었죠. 완전히 plain axios, 순수 axios에요. custom 설정이 전혀 되어있지 않았죠. 이 axios를 인스턴스(instance)라고 합니다. 우리의 입맛대로 변경해볼게요!
최상위 루트에 .env파일 만들고
REACT_APP_SERVER_URL=http://localhost:4000
기존 App.js에서 url들을
const { data } = await axios.get('${process.env.REACT_APP_SERVER_URL}');
이렇게 변경해준다.
### json-server 설정
<aside>
⚠️ json-server 설정을 먼저 해주세요!
</aside>
src > axios > api.js
```jsx
import axios from "axios";
// axios.create의 입력값으로 들어가는 객체는 configuration 객체에요.
// https://axios-http.com/docs/req_config
// 위 주소를 참고해주세요!
const instance = axios.create({
baseURL: "http://localhost:4000",
});
export default instance;
```
App.jsx
```jsx
import "./App.css";
import { useEffect } from "react";
import api from "./axios/api";
function App() {
useEffect(() => {
api
**.get("/cafe")**
.then((res) => {
console.log("결과 => ", res.data);
})
.catch((err) => {
console.log("오류가 발생하였습니다!");
});
}, []);
return <div>axios 예제입니다.</div>;
}
export default App;
```
자, get 요청하는 부분이 상당히 간결해졌죠. 이제는 서버의 정보가
- 변경 전 : http://localhost:3001
- 변경 후 : http://localhost:4000
이렇게 변경이 되어도, api.js 파일만 수정해주면 되겠어요!
- **(2) request, response에 적용해보기**
요청을 보낼 때, 그리고 서버로부터 응답을 받을 때(실패할 때) 특정한 일을 수행해야 한다면 어떻게 하면 될까요? 다음 코드를 적용해봅시다.
src > axios > api.js
```jsx
import axios from "axios";
const instance = axios.create({
baseURL: "http://localhost:4000",
});
instance.interceptors.request.use(
function (config) {
// 요청을 보내기 전 수행
console.log("인터셉트 요청 성공!");
return config;
},
function (error) {
// 오류 요청을 보내기 전 수행
console.log("인터셉트 요청 오류!");
return Promise.reject(error);
}
);
instance.interceptors.response.use(
function (response) {
console.log("인터넵트 응답 받았어요!");
// 정상 응답
return response;
},
function (error) {
console.log("인터셉트 응답 못받았어요...ㅠㅠ");
return Promise.reject(error);
}
);
export default instance;
```
브라우저에서 로그를 확인해보면

요청과 응답 중간에 **가로채서** 어떠한 작업을 수행해 주는 것을 볼 수 있죠!
- **(3) 실패 시켜보기**
이번에는 instance의 설정을 변경시켜서 요청을 실패시켜볼거에요.
```jsx
import axios from "axios";
// axios.create의 입력값으로 들어가는 객체는 configuration 객체에요.
// https://axios-http.com/docs/req_config
// 위 주소를 참고해주세요!
const instance = axios.create({
baseURL: "http://localhost:4000",
timeout: 1,
});
export default instance;
```
이렇게 변경해주게 되면, 요청 타임아웃이 1ms(1 밀리세컨)

말도 안되는 짧은 시간이기 때문에 서버에서 응답을 받기 전에 오류를 내게 될거에요. 해볼까요?

요청은 성공했지만, 응답을 못받았어요. 응답에 대한 로그를 살펴보면,
> 타임아웃 ‘1ms’을 초과하였습니다.
>
이네요.
## 3. 더 적용할 수 있는 부분
- 요청 시, content-type 적용
- token 등 인증 관련 로직 적용
- 서버 응답 코드에 대한 오류 처리(controller)
- 통신시작 및 종료에 대한 전역 상태를 관리하여 spinner, progress bar 등 구현 가능
사실, axios interceptor를 통해 통신의 중간과정에서 개발자의 머릿속에 있는 모든 것을 다 구현할 수 있어요.