🙆♀️
Axios をもっと使いやすくする設定
API とのデータ通信で Axios をよく使っています。少し前までは、以下のように Axios をインスタンス化した際に「共通と思われる」振る舞いを定義して利用していました。
参照: bulletproof-react/axios.ts at master · alan2207/bulletproof-react
import Axios, { AxiosRequestConfig } from 'axios';
import { API_URL } from '@/config';
import { useNotificationStore } from '@/stores/notifications';
import storage from '@/utils/storage';
function authRequestInterceptor(config: AxiosRequestConfig) {
const token = storage.getToken();
if (token) {
config.headers.authorization = `${token}`;
}
config.headers.Accept = 'application/json';
return config;
}
export const axios = Axios.create({
baseURL: API_URL,
});
axios.interceptors.request.use(authRequestInterceptor);
axios.interceptors.response.use(
(response) => {
return response.data;
},
(error) => {
const message = error.response?.data?.message || error.message;
useNotificationStore.getState().addNotification({
type: 'error',
title: 'Error',
message,
});
return Promise.reject(error);
}
);
しかし以下のようなケースもアプリケーション開発中に往々にして存在します。
- Axios インスタンスに設定した baseURL とは別のドメインの API へのアクセス
- アクセストークンが不要な API へのアクセス
- Auth0 を使うので、アクセストークンは React Hooks から取得したい
等々。こういった場合に先程の共通化した Axios インスタンスは利用できません。デフォルトの振る舞いを予め定義しておいて、Axios を利用する際に設定する方法のほうが使い勝手が良い気がします。
import Axios, { CreateAxiosDefaults } from "axios";
import camelcaseKeys from "camelcase-keys";
import snakecaseKeys from "snakecase-keys";
import { API_URL } from "@/config";
type HttpProps = {
isConvertKeys?: boolean;
accept?: string;
token?: string;
axiosDefaults?: CreateAxiosDefaults;
};
const defaultHttpProps: HttpProps = {
isConvertKeys: true,
accept: "application/json",
axiosDefaults: {
baseURL: API_URL,
},
};
export class Http {
public static axios(props?: HttpProps) {
const { axiosDefaults, isConvertKeys, accept, token } = {
...defaultHttpProps,
...props,
};
const axios = Axios.create({ ...axiosDefaults });
axios.interceptors.request.use((config) => {
if (config.headers && accept) {
config.headers.Accept = accept;
}
if (config.headers && token) {
config.headers.authorization = `bearer ${token}`;
}
if (isConvertKeys) {
config = snakecaseKeys(config);
}
return config;
});
axios.interceptors.response.use(
(response) => {
if (isConvertKeys) {
camelcaseKeys(response.data, { deep: true });
}
return response;
},
(error) => {
return Promise.reject(error);
}
);
return axios;
}
}
利用する際はこうします。
Http.axios({ token: 'xxxxx' }).get(....)
別の baseURL の API にアクセスしたい場合はこうします。
Http.axios({
axiosDefaults: {
baseURL: 'https://hogehoge.com',
}
}).get(...)
これでかなり使い勝手のよい Axios のラッパーになったかと思います。
Discussion