본문 바로가기
Mobile/ReactNative

[React Native] axios interceptors를 이용해서 헤더 업데이트하기

by 빠니몽 2024. 9. 29.

1. 기존 코드

// apiClient.ts
import axios from 'axios';
import { getBaseUrl } from '../constants/api';
import { getHeaders } from './headers';

const useApiClient = () => {
  const apiClient = axios.create({
    baseURL: getBaseUrl(),
    headers: getHeaders(),
  });

  return apiClient;
};

const apiClient = useApiClient();

export default apiClient;
// profile.tsx, 유저의 프로필을 api 요청으로 가져오는 코드
import axios from 'axios';
import apiClient from '../apiClient';
import { api } from '../../constants';

interface Profile {
    userId: number;
    name: string;
  }

interface ProfileResponse {
  success: boolean;
  message: string;
  data: Profile;
}

const getMyProfile = async (): Promise<ProfileResponse> => {
  try {
    const response = await (await apiClient).get<ProfileResponse>(api.ENDPOINTS.USER.PROFILE);
    return response.data;
  } catch (error) {
    if (axios.isAxiosError(error))
      throw new Error(error.response?.data.message || 'Failed to get profile');
    else
      throw new Error('Failed to get profile');
  }
};

export { 
  getMyProfile,
};

2. 문제점

실제로는 잘 동작할 것 처럼 보였지만, 그렇지 못했다. 

apiClient가 부팅 시점에만 한 번 불려진 후, 업데이트되지 않았기 때문이다.

headers에서 로그인 뒤 accessToken을 받아오려면 로그인 후에도 api 요청이 일어날 때마다 apiClient가 업데이트되어야 했다.

이것을 해결하기 위해 axios interceptor을 이용하기로 결정했다.

3. 수정된 코드

// apiClient.ts
import axios from 'axios';
import { getBaseUrl } from '../constants/api';
import { getHeaders } from './headers';

const apiClient = axios.create({
  baseURL: getBaseUrl(),
});

// Get updated headers
apiClient.interceptors.request.use(
  async (config) => {
    const headers = await getHeaders(); 
    // Merge with existing headers
    Object.entries(headers).forEach(([key, value]) => {
      config.headers.set(key, value);
    });
    return config;
  },
  (error) => {
    return Promise.reject(error);
  },
);

export default apiClient;

4. 왜 axios interceptors를 이용했는가?

기존의 코드에서 headers를 업데이트하려면 api call을 할 때 headers를 업데이트하여 넣어줘야 했다.

그렇게 된다면 apiClient자체를 없애고 콜을 할 때마다 AsyncStorage에서 accessToken을 불러주어야 했다.

실제로 이전 프로젝트에서 그렇게 진행했다.

그러나 그 때도, 지금도, 그러한 코드보다는 리팩토링하여 apiClient에서 한 번에 관리해서 api caller가 headers에 상관없이

api call을 하는 것이 더 낫다고 생각하였다.

이것이 axios interceptors를 도입한 이유이다.

'Mobile > ReactNative' 카테고리의 다른 글

[ReactNative] Image Url 렌더링  (0) 2024.07.21