내가 Axios Interceptor를 사용하는 방법
import { defineStore } from "pinia";
interface State {
loadingCnt: number;
loading: boolean;
}
export const useCommonStore = defineStore("common", {
state: (): State => {
return {
loadingCnt: 0,
loading: false,
};
},
actions: {
startLoading() {
this.loadingCnt += 1;
this.loading = true;
},
endLoading() {
this.loadingCnt -= 1;
},
cancelLoading() {
this.loadingCnt = 0;
this.loading = false;
},
},
});
import axios, { AxiosInstance } from "axios";
import { setupInterceptors } from "./interceptors";
export const createInstance = (): AxiosInstance => {
const instance = axios.create({
baseURL: "https://api.thecatapi.com/v1/images/search", // url
timeout: 15000,
});
return setupInterceptors(instance);
};
import axios, {
AxiosError,
AxiosInstance,
AxiosRequestConfig,
AxiosResponse,
} from "axios";
import { logOnDev } from "@/helpers/loghandler";
import { useCommonStore } from "@/store/common";
const onLoading = async (type: string) => {
const commonStore = useCommonStore();
const { startLoading, endLoading, cancelLoading } = commonStore;
switch (type) {
case "start": {
startLoading();
break;
}
case "end": {
endLoading();
break;
}
case "cancelLoading": {
cancelLoading();
break;
}
default: {
break;
}
}
};
const onRequest = (config: AxiosRequestConfig): AxiosRequestConfig => {
const { method, url } = config;
logOnDev(`🚀 [${method?.toUpperCase()}] ${url?.toUpperCase()} | START`);
onLoading("start");
return config;
};
const onRequestError = (error: Error | AxiosError): Promise<AxiosError> => {
logOnDev(`🚨 ${error.message}`);
onLoading("cancel");
return Promise.reject(error);
};
const onResponse = (response: AxiosResponse): AxiosResponse => {
const { status } = response;
const { method, url } = response.config;
logOnDev(
`🎉 [${method?.toUpperCase()}] ${url?.toUpperCase()} | SUCCESS ${status}`
);
onLoading("end");
return response.data;
};
const onResponseError = (error: AxiosError | Error): Promise<AxiosError> => {
if (axios.isAxiosError(error) && error.response) {
const { statusText, status } = error.response;
const { method, url } = error.config;
logOnDev(
`🚨 [${method?.toUpperCase()}] ${url?.toUpperCase()} | ${statusText} ${status}`
);
} else {
logOnDev(`🚨 ${error.message}`);
}
onLoading("cancel");
return Promise.reject(error);
};
export const setupInterceptors = (
axiosInstance: AxiosInstance
): AxiosInstance => {
axiosInstance.interceptors.request.use(onRequest, onRequestError);
axiosInstance.interceptors.response.use(onResponse, onResponseError);
return axiosInstance;
};
import { createInstance } from "@/api/index";
import axios from "axios";
interface CatDataType {
id: string;
height: number;
url: string;
width: number;
}
const getCatImg = async (): Promise<CatDataType> => {
try {
return await createInstance().get("/v1/images/search");
} catch (error) {
if (axios.isAxiosError(error)) {
throw error;
} else {
throw new Error("different error than axios");
}
}
};
코드 구조 잡을 때 유용했습니다 좋은 글 감사해요! 기능단위로 분리되어있어서 아주 깔끔정리 되었습니다.