그동안 작은 프로젝트를 수행하면, api 주소를 코드 안에 직접 넣었다.
그러다 보니 api url을 작성할 때 헷갈리는 부분이 많았고, 재사용에 대한 내용은 당연히 고려할 수 없었다.
그동안 내가 알던 axios는 단순히 axios가 아니다! 라는 것을 깨닫게 되었고, 이에 대해 배운 내용과 어떻게 하면 더욱 편리하고 효율적으로 api를 관리할 수 있는지에 대해서 정리해보고자 한다.
const getWeather = async() => {
try {
const weatherData = await axios({
method : 'get',
url : `https://api.openweathermap.org/data/2.5/weather?lat=${lat}&lon=${lon}&appid=${API_KEY}`
})
setWeather({
id : weatherData.data.weather[0].id,
main : weatherData.data.weather[0].main
})
}
catch (err) {
alert(err);
}
}
허허허.. 내가 작성했던 코드이다.
이렇게 작성하면 간단한 어플리케이션을 만들 때에는 별다른 문제가 없을 수 있다. 하지만 프로젝트 규모가 커지고 api를 사용하는 양이 많아지게 된다면 그 많은 api를 모두 관리할 수 없게 된다. 그렇기 때문에 이를 모듈화하여서 정리하고, 관리할 필요성이 있는 것이다.
만약 내가 특정 서버에 URL을 전달하는 프로젝트였다면 분명 아래와 같은 문제점을 겪었을 것이다.
이러한 문제점을 해결하기 위해서, axios를 인스턴스화 하여 모듈로써 관리를 할 수 있고, 앞으로 대규모의 프로젝트를 진행한다면 그와 같이 api 관리를 할 수 있어야 한다.
axios로 api를 관리하다 보면 항상 만나는 고민이다. 폴더를 어떻게 구성해야 할 지에 대한 고민이 참 많은데, API_모듈 구조라는 글을 참고하여 폴더 구조를 작성해 볼 수 있겠다.
📦 apis
┣ 📂 api(api request/response)
┃ ┗ user.js
┣ 📂 services(데이터를 정제)
┃ ┗ user.js
┣ 📂 utils(인스턴스/공통 함수 작성)
┃ ┗ instance.js
┗ index.js(모듈 export)
import axios from 'axios';
const instance = axios.create({
baseURL:"https://api.themoviedb.org/3",
params : {
api_key: process.env.REACT_APP_MOVIE_DB_API_KEY,
language : "ko-KR",
},
headers: {
access_token: cookies.get('access_token'),
}
});
export default instance;
axios.create
을 이용하여 직접 axios 인스턴스를 만들었다.
baseURL
은 서버의 기본 URL을 의미하고, headers
와 params
에 필요한 값들을 직접 지정할 수 있다.
이제 export한 axios 인스턴스를 직접 이용할 수 있다.
import axios from '../api/axois';
const fetchMovieData= async() => {
const request = await axios.get(fetchUrl);
setMovies(request.data.results);
}
이렇게 커스텀한 axios 인스턴스를 사용할 수 있다!
지금까지 axios로 api처리를 할 때 인터셉터를 어떻게 만들어야 할지에 대한 고민을 크게 진행하지 않고 무작정 try catch 구문을 사용하여 요청에 대하여 대응하였다. 이번 기회에 모듈을 정리하면서 api요청을 더욱 편리하게 처리할 수 있는 인터셉터 사용법에 대하여 정리하고자 한다.
interceptor는 말 그대로 가로채다
이다.
즉 axios로 요청을 보내기 전에 해당 request를 가로채서 할 일을 미리 한다는 것이다.
대표적으로 refreshToken을 처리할 때라고 할 수 있겠다.
내가 참고한 아래 글을 확인해보면 인증이 필요한 요청을 할 때마다 interceptor
를 사용하여 인증을 요청한다.
instance.interceptors.request.use(function(){});
use의 파라미터로는 요청을 가로채서 수행할 콜백 함수를 넣는 것이다.
instance.interceptors.request.use(
function (config) {
const accessToken = getCookie("accessToken");
if (accessToken && refreshToken) {
config.headers.common["Authorization"] = `${accessToken}`;
}
return config;
},
function (error) {
return Promise.reject(error);
}
);
accessToken과 refreshToken을 전달하는 방법이 되겠다.
instance.interceptors.response.use(
function (response) {
return response;
},
function (error) {
return Promise.reject(error);
}
);
서버에서 넘긴 정보를 매우 편리하게 관리할 수 있다. 에러를 더욱 촘촘히 관리하고 싶다면, 특정 status
일 때 알람을 띄우거나 다른 페이지로 이동시키게끔 할 수 있을 것이다.
항상 api 관련된 공부는 어렵다고 생각하고, 모듈을 따로 분리하기가 막상 어렵다고만 느껴졌었다. 하지만 이번 기회에 axios의 편리한 모듈 관리에 대하여 학습해 보니 나도 api 관리를 매우 깔끔하고 효율적으로 할 수 있을 것이라는 생각이 든다 💎