Axios - instance, interceptor

sudyn·2023년 5월 4일

브라우저(웹)

목록 보기
7/8

interceptor란?

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(=실패)가 처리되기 전

가로채서 어떤 역할을 하는 것이다.

따라서, 우리가 위에서 가정했던 상황들을 포함하여 요청 및 응답시에 필요한 작업들을 한꺼번에 처리할 수 있다.

  • 요청 헤더 추가
  • 인증 관리
  • 로그 관련 로직 삽입
  • 에러 핸들링

실습

baseURL 설정

const data = axios.get("http://localhost:4000/");

방법으로 데이터 통신을 해왔어요. axios를 썼었죠. 완전히 plain axios, 순수 axios에요. custom 설정이 전혀 되어있지 않았죠. 이 axios를 인스턴스(instance)라고 합니다. 우리의 입맛대로 변경해볼게요!

.env환경변수 설정

최상위 루트에 .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;
    ```
    
    브라우저에서 로그를 확인해보면
    
    ![Untitled](https://s3-us-west-2.amazonaws.com/secure.notion-static.com/0f9ab841-7701-4245-b6a9-7c09a20db30e/Untitled.png)
    
    요청과 응답 중간에 **가로채서** 어떠한 작업을 수행해 주는 것을 볼 수 있죠!
    
- **(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 밀리세컨)
    
    ![Untitled](https://s3-us-west-2.amazonaws.com/secure.notion-static.com/974f8c48-d9b6-4c5d-be6e-0d5f06c8057d/Untitled.png)
    
    말도 안되는 짧은 시간이기 때문에 서버에서 응답을 받기 전에 오류를 내게 될거에요. 해볼까요?
    
    ![Untitled](https://s3-us-west-2.amazonaws.com/secure.notion-static.com/fa5a108f-5981-40b1-be74-5c99430115e5/Untitled.png)
    
    요청은 성공했지만, 응답을 못받았어요. 응답에 대한 로그를 살펴보면,
    
    > 타임아웃 ‘1ms’을 초과하였습니다.
    > 
    
    이네요.
    




## 3. 더 적용할 수 있는 부분

- 요청 시, content-type 적용
- token 등 인증 관련 로직 적용
- 서버 응답 코드에 대한 오류 처리(controller)
- 통신시작 및 종료에 대한 전역 상태를 관리하여 spinner, progress bar 등 구현 가능

사실, axios interceptor를 통해 통신의 중간과정에서 개발자의 머릿속에 있는 모든 것을 다 구현할 수 있어요.
profile
개발계발하는 프론트엔드 개발자🍠

0개의 댓글