React

axios instance 만들기

hihiha2 2023. 8. 20. 17:23
const fetchData = async () => {
    // 현재 상영중인 영화 정보를 가져오기 (여러영화)
    const request = await axios.get(requests.fetchNowPlaying);
    console.log(request);
    
    //0번째 영화의 id만 가져오기
    const movieID = request.data.results[0].id;
    console.log(movieID);

    //0번째 영화의 상세정보 가져오기
    const {data: movieDetail} = await axios.get(`movie/${movieID}`)
    console.log(movieDetail)
  };

axios는?

Axios는 라우저, Node.js를 위한 Promise API 활용하는 HTTP 비동기 통신 라이브러리

Axios는 웹 애플리케이션에서 HTTP 요청을 보내고 응답을 받는 데 사용되는 JavaScript 라이브러리로, 서버와 통신할 때 자주 사용된다.

 

 


1. 기능

반복되는 코드를 인스턴스화함으로써 코드의 가독성과 재사용성을 높임

 

 

2. 방법

1️⃣ 만들기

const instance = axios.create({

baseURL:

Params: 

등등.. 

})

// Axios 인스턴스 생성
const instance = axios.create({
  baseURL: 'https://api.example.com',
  timeout: 10000,
});

 

2️⃣ 사용하기

api 불러오기 - instance.get()

.then / .catch 사용

// Axios 인스턴스를 사용하여 GET 요청 보내기
instance.get('/data')
  .then(response => {
    // 응답 처리
  })
  .catch(error => {
    // 오류 처리
  });

 

async/await 사용

const fetchData = async()=> {
  try {
    const response = await instance.get('/data');
    // 응답처리
  } catch (error) {
    // 응답처리
  }
}

 

 

사용법 | Axios 러닝 가이드

사용법 GET 요청 axios를 사용해 GET 요청하는 방법은 다음과 같습니다. const axios = require('axios'); axios.get('/user?ID=12345') .then(function (response) { console.log(response); }) .catch(function (error) { console.log(error); }) .t

yamoo9.github.io

 


 

🔫 instance를 만드는 이유

instance를 만드는 이유를 알기 위해서는 우선적으로 객체지향프로그래밍클래스인스턴스에 대한 개념이해가 필요하다.

(이 글의 작성이유는 axios instance만들기가 초점이므로 객체지향에 대한것은 간단하게만 적을 것이다.)


🔎 객체지향프로그래밍(OOP)이란?

소프트웨어를 개발하는 데 사용되는 프로그래밍 패러다임 중 하나

프로그램을 개체(Object) 중심으로 설계하고 구성하는 방법론

목표: 코드를 더 모듈화하고 추상화하여 프로그램의 복잡성을 줄이고 유지보수를 쉽게 만드는 것

 

구성: 클래스 / 인스턴스

  • 클래스(Class): 클래스는 객체를 만들기 위한 일종의 청사진(blueprint) 또는 템플릿(template). 클래스는 객체가 가져야 할 속성(attribute)과 메서드(method)를 정의
  • 인스턴스(Instance): 클래스를 기반으로 만들어진 실제 객체. 클래스의 인스턴스는 클래스에 정의된 속성과 메서드를 가지며, 서로 다른 인스턴스는 독립적으로 상태를 관리할 수 있다.

 

객체지향프로그래밍은 클래스와 인스턴스로 구성되어있는데, 자주 사용하는 틀을 정의하는 것을 클래스, 그 틀을 기반으로 원하는 구체적인 내용을 넣은 것인스턴스라고 이해하면 이해가 조금 더 쉽다. 보통 클래스와 인스턴스는 붕어빵틀과 붕어빵속재료에 비유를 많이 한다. 

클래스-붕어빵틀, 인스턴스-붕어빵속재료이며 한번 만들어놓은 클래스를 기반으로 안에 어떤재료를 채워넣느냐에 따라서 다른 결과가 나온다. 요리사는 클래스를 이용함으로써 매번 붕어빵모양을 만들필요없이 팥을 넣은 팥붕어빵, 슈크림을 넣은 슈크림붕어빵.. 등등 다양한 붕어빵을 만들 수 있다.


 

Axios에서 사용되는 클래스Axios 라이브러리 내부에 정의되어 있으며 HTTP 클라이언트의 기능과 설정을 추상화하는 역할을 한다.

이러한 클래스를 기반으로 사용자는 원하는대로 인스턴스를 생성하여 원하는 속재료를 채워줄 수 있는것이다.

이때 속재료로 들어가는 것을에는 여러가지가 있을 수 있는데 baseURL, header, params등 다양하다.

 

이렇게 만든 인스턴스를 기반으로 한번 만들면 그 위에 다른것들은 손쉽게 추가를 할 수 있게 된다.

예를 들면 팥붕어빵 위에 크림올리기 / 아이스크림올리기 등의 내용을 더 추가하고 싶다면, 이제 요리사는 한번 만들어진 팥붕어빵을 처음부터 다시 만들 필요가 없이 만들어놓은 팥붕어빵(인스턴스)위에 올라갈 고명만 골라주면 되는 것이다. 

 

이렇게하면 클래스(붕어빵틀)-인스턴스(붕어빵속재료)-응용(고명올리기).. 와 같은 과정중 앞의 2개는 한번만 만들어놓으면 계속해서 고명올리기만 추가해서 쓰면 되기 때문에 코드도 짧아지고 가독성도 올라가 모든 코드를 일일이 적을 필요가 없어지고 유지보수도 편해진다.

 

 

 

🕹 instance 만드는 방법

1. api 폴더만들고 안에 axios.js / requests.js 파일만들기

api를 위한 인스턴스를 만드는 것이므로, 보통 폴더명은 api라고 짓는다.

파일명은 적당히 원하는이름으로 지어주면 된다. 

폴더의 위치는 src하위이다. 

 

2. axios.js안에 instance 구체적으로 만들기

import axios from "axios";

const instance = axios.create({
  baseURL: "https://api.themoviedb.org/3",
  params: {
    api_key: "2211333",
    language: "ko-KR",
  },
});

export default instance;

1️⃣ 최상단에 axios를 import한다.

2️⃣ instance라는 이름의 변수를 짓고, axios.create()를 사용하여 instance를 만든다.

3️⃣ {} 안에 axios.create 메서드의 설정 옵션을 적는다.

인스턴스화하여 넣고 싶은 것을 넣는다. 보통 baseURL을 기본으로 넣고, 나머지는 원하는대로 옵셔널하게 넣는다.

(인스턴스화하는 이유자체가 반복되는 코드를 일일이 적는것을 개선하기 위해서이므로 본인의 api통신 코드중 계속해서 반복되는 내용을 넣어주면 된다.)

 

✚ axios.create 메서드의 설정 옵션

  1. baseURL: 이 옵션을 사용하면 모든 요청의 기본 URL을 설정할 수 있다. 이후 요청에서 상대적인 URL을 사용할 때 baseURL을 기준으로 요청이 만들어진다.
  2. timeout: 요청의 타임아웃 설정. 밀리초 단위로 설정하며, 요청이 지정된 시간 내에 응답하지 않으면 타임아웃으로 처리된다.
  3. headers: 요청 헤더를 설정할 수 있는 객체. 이 헤더는 모든 요청에 추가된다.
  4. params: 기본적으로 요청에 추가할 쿼리 매개변수를 설정할 수 있다. 이 매개변수는 모든 요청에 자동으로 추가된다.
  5. auth: HTTP 기본 인증을 사용할 때 사용자 이름과 비밀번호를 설정할 수 있다.
  6. 기타 옵션: Axios에서 지원하는 다양한 옵션들이 있다. 예를 들어 withCredentials를 사용하여 요청 시 쿠키를 전송할지 여부를 설정할 수 있다.
{
  baseURL: "https://api.themoviedb.org/3",
  params: {
    api_key: "2211333",
    language: "ko-KR",
  },

나는 tmdb의 openAPI를 불러오는 코드를 짜기위해서 baseURL을 설정옵션으로 넣고 tmdb의 baseURL를 넣어주었다.

그리고 params안에 api키와 언어를 추가적으로 적었다. 

 

4️⃣ instance를 default로 export해준다.

 

3. requests.js 안에 requests 구체적으로 만들기

requests는 모든 api통신에 필요한 내용은 아니라서 필수적으로 만들어야하는 건 아닌 것같다.

 

내가 만들고 있는 사이트는 영화api를 불러오는데, 이때 다양한 옵션에 의해서 불러와야한다. 

예를 들면 Action영화 api불러오기, Comic영화 api 불러오기, Romance영화 api 불러오기 등등.. 다양한 방법으로 불러와야한다.

const requests = {
  fetchNowPlaying: `/movie/now_playing`,
  fetchNetflixOriginals: `/discover/tv?with_networks=213`,
  fetchTrending: `/trending/all/week`,
  fetchTopRated: `/movie/top_rated`,
  fetchActionMovies: `/discover/movie?with_genres=28`,
  fetchComedyMovies: `/discover/movie?with_genres=35`,
  fetchHorrorMovies: `/discover/movie?with_genres=27`,
  fetchRomanceMovies: `/discover/movie?with_genres=10749`,
  fetchDocumentariesMovies: `/discover/movie?with_genres=99`,
};

export default requests;

이때 앞의 baseURL과 params부분은 동일하다. 따라서 인스턴스화한 axios를 이용하고 그 안에서 구체적으로 한번 더 어떤 값을 request할지를 미리 변수화하여 사용시에 계속해서 일일이 적을 수고를 덜어주는 역할을 한다.

 

axios.get(requests.fetchNowPlaying)과 같은 형식으로 현재 상영중인 영화 정보만을 가져올 수 있다.

 

일단 이렇게하면 앞으로 반복적으로 사용할 API의 인스턴스화는 끝났다. 만들어진 인스턴스를 기반으로 사용만 해주면 된다.

 

 

✅ instance 사용하기

현재 상영중인 영화만을 받아오는 api를 짠다고 해보자.

main.js에서 api를 받아온다고 가정하였다.

 

1️⃣ axios.js로부터 인스턴스 import하기

import axios from "../../api/axios";

2️⃣ requests.js로부터 인스턴스 import하기

import requests from "../../api/requests";

 

3️⃣ 사용할 파일 (Main.js)에서 instance.get(세부적 request)를적는다.

// Main.js

import React, { useEffect } from "react";
import axios from "./api/axios";
import requests from "./api/requests";

export default function Main() {

  const fetchData = async() => {
    // 현재 상영중인 영화 정보를 가져오기 (여러영화)
    const request = await axios.get(requests.fetchNowPlaying);
    console.log(request);
  };

  useEffect(()=>{
    fetchData()
  },[])

  return <div style={{fontSize:100}}>현재상영중인 영화</div>;
}

화면에 띄우는 코드는 짜지 않고 api 통신이 잘되는지만을 확인하기 위해서 console을 통해서 값이 잘 들어왔는지만 확인하였다.

 

원래 instance를 "./api/axios";로 부터 import하고 instance.get()으로 api를 호출해야하는데, instace가 default이기때문에 저렇게 axios라는 이름으로 적고 axios.get()으로 호출해도 정상작동한다.

 

우선 api를 통해서 data를 뭉탱이로 받아온다. 그 데이터중 하나만을 선택하여 화면에 띄우기등의 작업을 해야하므로 받아온 뭉탱이 데이터를 request라는 변수에 담는다. (이후에 일일이 적을 필요없이 변수를 통해서 데이터를 가공해서 사용하기 위해서)

 

fetchData()함수를 호출하면 통신이 시작되어 데이터가 get되는데, 위와 같이 렌더링을 안하고 자료만 받아오는 상황이 아니라 받아온 자료를 바탕으로 state를 변경하는 경우라면(대부분의 일반적인 경우), state변경시 리렌더링이 일어나는 리액트의 성질때문에

① 리렌더링이 일어나면서 ➡️ ②다시 함수를 호출하여 api통신이 이루어지고 ➡️③ state가 다시 업데이트되고

④ 리렌더링이 일어나면서  ➡️ ⑤다시 함수를 호출하여 api통신이 이루어지고 ➡️⑥ state가 다시 업데이트되고

.... 의 상황이 반복된다. 

 

이를 방지하기 위해서 fecthData를 useEffect안에 넣어줌으로써 초기렌더링시에만 api를 호출하게 만든다.

현재상영중인 영화만을 데이터로 잘 받아왔는지 콘솔을 통해서 확인하면 아래와 같다.

 

 

이렇게 받아온 데이터뭉치가 잘 도착했는지 console을 통해서 확인한다.

 

데이터가 객체의 형태로 잘 들어온 것을 확인할 수 있다.

 

 

만약여기에서 하나의 최신영화를 받아오고 싶다면 객체중 하나의 값만을 선택해서 받아오면 된다.

눌러서 확인해보면 위와 같은 구조를 가지고 있다. 만약 이중 첫번째 영화의 id만을 받아오고 싶다면 data.results.[0].id와 같은 방법으로 특정값만 부를 수 있다.

const fetchData = async () => {
    // 현재 상영중인 영화 정보를 가져오기 (여러영화)
    const request = await axios.get(requests.fetchNowPlaying);
    console.log(request);
    
    //0번째 영화의 id만 가져오기
    const movieID = request.data.results[0].id;
    console.log(movieID);

  };

 

 

콘솔을 통해서 확인하면 ID값만을 불러오는 것을 확인할 수 있다.

이렇게 받아온 id를 이용해서 특정한 영화의 이미지나 title등의 더 자세한 정보만을 취할 수 있다.

 

 

현재상영중인 영화의 0번째값의 ID를 이용하여 상세정보를 가져온다.

const fetchData = async () => {
    // 현재 상영중인 영화 정보를 가져오기 (여러영화)
    const request = await axios.get(requests.fetchNowPlaying);
    console.log(request);
    
    //0번째 영화의 id만 가져오기
    const movieID = request.data.results[0].id;
    console.log(movieID);

    //0번째 영화의 상세정보 가져오기
    const {data: movieDetail} = await axios.get(`movie/${movieID}`)
    console.log(movieDetail)
  };

위의 코드에서 axios.get(`movie/${movieID}`)와 같이 적어서 받아온 이유는 TMDB의 공식문서를 보면 알 수 있다.

특정값을 받아오기 위해서 사용되는 값은 약속된 값이 있기때문에 그것을 참고해서 적어야 정상적으로 코드가 작동한다.

 

TMBD의 공식문서를 통해 확인하면 현재 상영중인 영화의 정보를 받아오기 위해서는 baseURL/movie/{movie ID}가 들어가야 함을 확인할 수 있다. 보통 이렇게 약속된 url로 받아올 주소를 정해놓고 프론트엔드는 그것을 잘받아와서 화면에 띄우는 역할을 하게 된다.

 

 

위에서 받아온 값의 title과 이미지를 화면에 띄운다면, 아래와 같이 나타낼 수 있다.

import React, { useEffect, useState } from "react";
import axios from "./api/axios";
import requests from "./api/requests";

export default function Main() {
  //useState를 통해서 state값 변경
  const [movie, setMovie] = useState([]);

  // api통신을 할 함수
  const fetchData = async () => {
    // 현재 상영중인 영화 정보를 가져오기 (여러영화)
    const request = await axios.get(requests.fetchNowPlaying);
    console.log(request);

	// 0번째 영화 ID
    const movieID = request.data.results[0].id;
    console.log(movieID);

	//ID를 통해서 특정영화의 상세정보가져오기
    const { data: movieDetail } = await axios.get(`movie/${movieID}`);
    setMovie(movieDetail);
  };

  //useEffect를 통해서 fetchData함수 무한반복 막기
  useEffect(() => {
    fetchData();
  }, []);

  return (
    <div style={{ fontSize: 100 }}>
      현재상영중인 영화
      //url을 통해서 배경이미지 가져오기
      <div
        style={{
          backgroundImage: `url("https://image.tmdb.org/t/p/original/${movie?.backdrop_path}")`,
          backgroundPosition: "top center",
          backgroundSize: "cover",
          height: "500px",
        }}
      >
      // 영화제목 가져오기
        <p>{movie.title}</p>
      </div>
    </div>
  );
}

 백그라운드이미지는 url을 통해서 가져올 수 있다.

이것또한 TMDB의 공식문서를 통해서 확인할 수 있다.

 

Basics

How to build an image URL.

developer.themoviedb.org

 

 

🙋‍♀️ 내 생각

axios의 instance를 만드는 방법에 대해 정확하게 이해하고 정리하기 위해서 글을 쓰다보니 이런 저런 내용이 합쳐져서 조금 길어진 것 같다. instance를 만들기에 앞서 이게 무엇이고 왜 이걸 만드는 지에 대한 이해가 필요하고 또 그것을 구체적으로 어떻게 활용할 수 있는지에 대해서도 알고 있어야한다. api를 통해 받아오는 데이터를 콘솔로 확인해가면서, 또 공식문서나 아니면 백엔드와 어떤 url을 통해서 받아올지에대한 약속을 한 것을 확인하면서 데이터가 어떤 형식으로 들어오는지를 알아야한다. 그것을 바탕으로 받아온 데이터를 가공하고 그 중 필요한 것들만을 골라서 화면에 띄우는 역할을 해야할 것이다. 

 

axios의 인스턴스를 만드는 이유와 활용법을 중점으로 공부하고 글을 써보았는데, 다음에는 axios는 무엇이고 왜 사용하는지 또 그안에서 사용하는 .then/.catch나 async/await에 대해 공부하고 글을 작성하고 싶다.