React & React Native/라이브러리 활용

[RN] React Native 모바일 기기에서 API 통신 방법 이해하고 설정하기 : axios

adjh54 2023. 6. 20. 20:38
반응형
해당 글에서는 React-native 환경에서 Axios 기반의 API 통신을 하는 방법에 대해 이해하고 Fetch API와 비교하여 Axios만의 특징에 대해서 확인해 보는 목적으로 작성한 글입니다.


 

1) Axios


💡 Axios

- Node.js와 브라우저를 위한 Promise 기반 HTTP 클라이언트입니다.
- XMLHttpRequests(XHR)를 처리하는 데 사용이 되며 이를 통해 비동기적으로 데이터를 가져오는 역할을 수행합니다.

 
 

[ 더 알아보기 ]

💡 XMLHttpRequests(XHR)

- 클라이언트와 서버 간의 비동기적 데이터 전송을 위해 사용되는 JavaScript API를 의미합니다.
- 이 API를 사용하면 웹 페이지를 새로고침하지 않고도 서버로 데이터를 보내거나 서버에서 데이터를 가져올 수 있습니다.

 
 

2) Axios 주요 기능들


기능 설명
XMLHttpRequests 생성 기능  브라우저에서 서버로 데이터를 보낼 때 사용되는 객체를 생성하는 기능을 제공합니다
http 요청 생성 기능 node.js에서 서버로 데이터를 보낼 때 사용되는 요청 객체를 생성하는 기능을 제공합니다
Promise API 기능 비동기 작업을 처리할 때 사용되는 Promise 객체를 지원하는 기능을 제공합니다
요청 및 응답 인터셉트 기능 요청이나 응답이 발생할 때, 그에 대한 처리를 중간에서 가로채서 추가적인 작업을 할 수 있는 기능을 제공합니다
요청 및 응답 데이터 변환 기능 요청이나 응답 데이터를 다른 형식으로 변환할 수 있는 기능을 제공합니다
요청 취소 기능 요청을 취소하는 기능을 제공합니다
JSON 데이터 자동 변환 기능 JSON 형식으로 요청이나 응답 데이터를 자동으로 변환하는 기능을 제공합니다
XSRF를 막기 위한 클라이언트 사이드 지원 기능 클라이언트 측에서 XSRF(Cross-Site Request Forgery) 공격을 막기 위한 처리를 지원하는 기능을 제공합니다

 
 
 

3) Axios 사용하기 : REST API와 통신


 

1. 라이브러리 설치


# axios 라이브러리 설치 (npm)
$ npm i axios

# or

# axios 라이브러리 설치 (yarn)
$ yarn add axios

 

 

2. 동기(Synchronous) 처리 방식


💡 동기(Synchronous) 처리 방식

- 어떠한 데이터 통신을 위해 ‘요청'을 하였을 때, 어떠한 요청에 대한 ‘응답'을 받을 때까지 기다리다가 완료된 뒤 다음 코드가 수행되는 처리방식을 의미합니다.
- 기본적으로 '비동기 처리 방식'을 수행합니다. 이를 동기 처리방식으로 처리하기 위해서는 async-await 기능을 사용합니다.

 

💡 모두 await 키워드를 사용하여 Promise가 처리될 때까지 대기합니다.
const RestAPIRequest = () => {

    useEffect(() => {
        requestGet();
        requestPost();
        requestPut();
        requestDelete();
    }, []);

    // GET
    const requestGet = async () => {
        try {
            const response = await axios.get('<https://jsonplaceholder.typicode.com/posts>');
            console.log(response.data);
        } catch (error) {
            console.error(error);
        }
    }

    // POST
    const requestPost = async () => {
        const data = {
            title: 'foo',
            body: 'bar',
            userId: 1
        };

        try {
            const response = await axios.post('<https://jsonplaceholder.typicode.com/posts>', data);
            console.log(response.data);
        } catch (error) {
            console.error(error);
        }
    }

    // PUT
    const requestPut = async () => {
        const data = {
            title: 'foo',
            body: 'bar',
            userId: 1
        };
        try {
            const response = await axios.put('<https://jsonplaceholder.typicode.com/posts/1>', data);
            console.log(response.data);
        } catch (error) {
            console.error(error);
        }
    }

    // DELETE
    const requestDelete = async () => {
        try {
            const response = await axios.delete('<https://jsonplaceholder.typicode.com/posts/1>');
            console.log(response.data);
        } catch (error) {
            console.error(error);
        }
    }
}
export default RestAPIRequest;

 
 
 

3. 비동기(Asynchrous) 처리 방식


 💡 비동기(Asynchrous) 처리 방식이란?

- 어떠한 데이터 통신을 위해 ‘요청’을 하였을 때, 어떠한 요청에 대한 ‘응답'을 기다리지 않고 다음 코드가 수행되는 처리방식을 의미한다

 

3.1. 구현부


import axios from "axios";

class RequestService {

    requestHttpGet = () => {
        return axios({
            method: 'get',
            url: "<https://jsonplaceholder.typicode.com/posts>",
        });
    }

    requestHttpPost = (data) => {
        return axios({
            method: 'post',
            url: '<https://jsonplaceholder.typicode.com/posts>',
            data: data
        });
    }

    requestHttpPut = (data) => {
        return axios({
            method: 'put',
            url: '<https://jsonplaceholder.typicode.com/posts>',
            data: data
        });
    }

    requestHttpDelete = (data) => {
        return axios({
            method: 'delete',
            url: '<https://jsonplaceholder.typicode.com/posts>',
            data: data
        });
    }

}
export default new RequestService();

 
 
 

3.2. 호출부


const RequestScreen = () => {
  useEffect(() => {
    RequestService.requestHttpGet()
      .then((req) => {
        console.log("결과값 :: ", req)
      }).catch((err) => {
        console.log("에러 메시지 ::", err)
      });

    const data = { title: 'foo', body: 'bar', userId: 1 };

    RequestService.requestHttpPost(data)
      .then((req) => {
        console.log("결과값 :: ", req)
      }).catch((err) => {
        console.log("에러 메시지 ::", err)
      });

    RequestService.requestHttpPut(data)
      .then((req) => {
        console.log("결과값 :: ", req)
      }).catch((err) => {
        console.log("에러 메시지 ::", err)
      });

    RequestService.requestHttpDelete(data)
      .then((req) => {
        console.log("결과값 :: ", req)
      }).catch((err) => {
        console.log("에러 메시지 ::", err)
      });
  })

}
export default RequestScreen;

 

💡 [참고] Promise에 대해 궁금하시면 아래의 링크가 도움이 됩니다.
 

[JS] Promise 이해하기 -1 (콜백함수, 정의, 요청상태)

해당 글은 Promise를 사용하기 이전에 callback 함수를 사용할 때와의 비교 및 Promise에 대한 이해 그리고 Promise의 요청 상태에 대해서 이해하기 위한 글입니다 1. Promise를 사용하기 이전 비동기 처리

adjh54.tistory.com

 

[JS] Promise 이해하기 -2 (Promise 체이닝, Promise.all, async/await)

해당 글은 이전 Promise에 대한 정의에 이어서 추가로 이해할 Promise Chaning, Promise.all 그리고 async/await 구문에 대해서 이해하기 위한 글입니다. 이전 Promise에 대한 정의가 궁금하면 아래에 이전 글을

adjh54.tistory.com

 
 
 

4) Axios vs Fetch API 비교


 💡 fetch API

- JavaScript에서 제공하는 HTTP 요청을 위한 API입니다. 
- 이는 XMLHttpRequest 보다 쉽게 사용할 수 있으며, Promise 객체를 사용하여 비동기적으로 데이터를 처리할 수 있습니다.
분류 Fetch API Axios
제공자 내장 API 서드파티 라이브러리
크기 내장 API이므로 별도의 설치가 필요 없음 29.5kB (미니파이드), 11.2kB (미니파이드+Gzip)
라이센스 React Native와 동일함(MIT) MIT
유지보수 내장 API여서 유지보수는 없습니다 활발한 유지 보수
요청 및 응답 interception X O
요청 및 응답 변환 지원 X O
자동 JSON 변환 지원 X O
요청 취소 지원 O O
요청 시간 초과 지원 O O
Promise 기반 O O

 
 
 
 

5) Fetch API와 다른 점 : Axios만의 특징


 

1. 인터셉터를 사용한 통신


💡 클라이언트에서 서버로 API 호출을 하는 경우에 ‘토큰’을 포함하는 경우가 많습니다.
💡 그렇기에 인터셉터 기능을 사용하여서 API 호출할 때 요청에 토큰을 포함합니다.

 

const [userToken, setUserToken] = useState("");

const tempUserToken = "temp Token";

// 토큰이 존재하지 않는 경우 Axios로 API 호출 통신시 생성된 토큰에 따라서 수행한다.
axios.interceptors.request.use((config) => {
if (userToken === "") {
  config.headers.Authorization = `BEARER ${tempUserToken}`;
  console.log("interceptors :: ", config)
}
return config;
})

 
 
 

2. 요청/응답 JSON 형태 변환


 

2.1. Fetch API

💡 내부 fetch AP를 사용하는 경우 요청 시

1. body로 객체를 그래도 전송할 수 없기에 JSON.stringify()를 통해 JSON 형식으로 직렬화를 통해서 전송합니다.
2. 결과값(res)으로 받은 값을 다시 .json() 형태로 파싱을 합니다.

그렇기에 하나의 API 호출에도 두 번의 JSON 변환이 이루어지는 번거로움이 있습니다.
const selectUser = () =>{
		fetch('/api/v1/user/selectUser', {
		    method: "POST",
		    headers: {'Content-Type': 'application/json'},
		    body: JSON.stringify({"userId": userId})
		})
    // Response 데이터 파싱
    .then((response) => response.json())
    .then((res) => {
        const {result, resultCode} = res;
    })
    .catch((request, status, error) => {
        alert(`에러가 발생하였습니다 ${request}, ${status}, ${error}`)
    });
}

 
 
 

2.2. Axios


💡 Axios의 요청/응답에 대한 JSON 변환 기능을 통해서 별도의 변환 필요 없이 요청과 응답 값이 JSON 형태로 수행되는 것을 확인하였습니다.
import axios from 'axios';

const selectUserAxios = () =>{
        axios({
            method: 'post',
            url: '/api/v1/user/selectUser',
            data: {"userId": userId}
        })
        .then((res)=>{
            const {result, resultCode} = res;
        })
        .catch((request, status, error) => {
            alert(`에러가 발생하였습니다 ${request}, ${status}, ${error}`)
        });
    }
}

 

 

 

 

6) 참고 : 로컬 서버에 API 통신을 하는 경우


💡 로컬 서버로 API 통신을 하는 경우 'AxiosError: Network Error' 에러가 발생합니다.

 

 

💡 해결방법

1. 모바일기기와 동일한 Wifi를 사용합니다.
2. 아래의 과정을 통해 IP 주소를 확인합니다.

 

1. 시스템 환경설정을 선택합니다.


 

 

2. Wi-Fi 탭 - 연결된 Wi-Fi의 '세부사항..' 버튼을 선택합니다.


 

 

3. IP 주소 확인하여 localhost 대신하여 작성합니다.


 

 
 
 
오늘도 감사합니다. 😀
 
 
 
 

반응형