기존에는 serverURL
을 전역에서 사용할 수 있는 공통 상수로 만들어 두고 이를 import하는 식으로 baseQuery
에서 baseUrl
을 지정하여 사용하고 있었다.
const serverURL = "https://...";
export const authApi = createApi({
reducerPath: "auth",
baseQuery: fetchBaseQuery({
baseUrl: `${serverURL}/v1/auth`,
}),
endpoints: (builder) => ({
// ...
}),
});
하지만 특정 state를 기준으로 동적으로 server url을 변경해야 하는 요구사항이 생겼다. 어떻게 구현해야 좋을지 고민하며 이런 저런 방법을 찾아보던 중, 해당 state를 redux state로 저장한 뒤, baseQuery
를 함수 꼴로 사용하여 이를 읽어오는 방식으로 구현하기로 결정하였다.
대강의 구현 방식은 다음과 같다. baseQuery
를 함수 꼴로 사용하면 두번째 인자를 통해 현재 redux state를 읽어올 수 있게 된다. redux state 내에 server url을 관리하는 serverUrl
이라는 상태가 있다고 가정하면,
export const authApi = createApi({
reducerPath: "auth",
baseQuery: (args, baseQueryApi, options) => {
const baseUrl = (baseQueryApi.getState() as CustomReduxState).serverUrl;
return fetchBaseQuery({ baseUrl: `${baseUrl}/v1/auth` })(args, baseQueryApi, options);
},
endpoints: (builder) => ({
// ...
}),
});
이런 식으로 불러올 수 있게 되는 것이다. return value로 기존의 fetchBaseQuery
를 호출한 뒤 인자를 전부 넘겨주면 끝이다. 이를 조금 더 고도화 해 보자.
baseQuery
를 함수 꼴로 사용하기 위한 함수를 dynamicBaseQuery
라는 별도의 함수로 분리하고, 이를 baseUrlPath를 구체적으로 명시하는 것까지 공통함수화 하는 고차 함수로 작성하였다. 전체 코드는 다음과 같다.
import { BaseQueryFn, FetchArgs, FetchBaseQueryError, fetchBaseQuery } from "@reduxjs/toolkit/query/react";
/**
* redux toolkit slice의 base query를 동적으로 생성하는 함수. redux state 내 `baseUrl`에 따라 서버 URL이 변경됨.
* @param baseUrlSuffix 공통으로 `baseUrl`에 넣을 path
*/
export function dynamicBaseQuery(baseUrlSuffix: string): BaseQueryFn<string | FetchArgs, unknown, FetchBaseQueryError> {
return (args, baseQueryApi, extraOptions) => {
const serverUrl = (baseQueryApi.getState() as ReduxState).serverUrl;
const baseUrl = serverUrl.concat(baseUrlSuffix.startsWith("/") ? "" : "/").concat(baseUrlSuffix);
const rawBaseQuery = fetchBaseQuery({ baseUrl });
return rawBaseQuery(args, baseQueryApi, extraOptions);
};
}
export const authApi = createApi({
reducerPath: "auth",
baseQuery: dynamicBaseQuery("/v1/auth"),
endpoints: (builder) => ({
// ...
}),
});
dynamicBaseQuery
에 baseUrlSuffix
를 넘겨주어 기존 baseUrl
state 뒤에 붙는 세부 path를 입력할 수 있다. 이 함수를 import하여 baseQuery
를 동적으로 생성하는 slice를 여러 개 만들 수 있다.
https://stackoverflow.com/questions/69568818/how-to-dynamically-change-base-url-using-redux-toolkit