Description
Scenario
I have a monorepo setup made with nx which contains 2 web apps and a set of libs. Libs are splitted as shared-lib and admin-lib. Each lib has it's own redux setup (store, slices and rtkq apis). Given that for my admin app I've created a dedicated admin-lib, there is an rtkq api which I want to extend from the shared-lib.
All good so far, i can use mySharedApi.injectEndpoints({...})
and it works.
Problem
Both APIs have their own custom implementation of baseQuery, on admin one I also have a handler for when an api endpoint gives 403 and dispatches an action inside it's custom baseQuery implementation to notify the app the user isn't allowed to access certain resources. But since I need some endpoints only from the sharedApi, that api isn't linked to second baseQuery, therefore the admin one isn't called.
Summary
How can i merge 2 API endpoints and override the baseQuery from the one that's extended.
Some code for reference:
export const adminApi = sharedApi.injectEndpoints({
_reducerPath: 'adminApi',_
_baseQuery: baseAdminQueryWithReauth({ baseUrl: 'resource', retries: 3 }),_ << custom baseQuery with 403 handler
_tagTypes: ['Resources'],_
endpoints: builder => ({
getAdminResources: builder
.query<any, Partial<any>>({
query: query => '/v2/search?${ stringify(query) }',
providesTags: ['Resources'],
}),
});
export const sharedApi = createApi({
reducerPath: 'sharedApi',
baseQuery: baseQueryWithReauth({ baseUrl: 'resource', retries: 3 }), << custom baseQuery **without** 403 handler
tagTypes: ['Resources'],
endpoints: builder => ({
someNonAdminEndpoint: builder
.query<any, Partial<any>>({
query: query => '/v2/search?${ stringify(query) }',
providesTags: ['Resources'],
}),
});
export const createBaseQuery = ({ baseUrl = '', retries = 0 }) => {
const baseQuery = fetchBaseQuery({
baseUrl: `/api/${ baseUrl }`,
prepareHeaders: (headers) => {
// By default, if we have a token in the store, let's use that for authenticated requests
const token = getFromLocalStorage(LOCAL_STORAGE_DATA_KEY.idToken);
if (token) {
headers.set('Authorization', token);
}
return headers;
},
});
if (retries) {
return retry(baseQuery, { maxRetries: retries - 1 });
}
return baseQuery;
};
export const baseAdminQueryWithReauth = (props: BaseQueryPropTypes) => {
const fn: BaseQueryFn<string | FetchArgs, unknown, FetchBaseQueryError> = async (
args,
api,
extraOptions
): Promise<any> => {
const result = await createBaseQuery(props)(args, api, extraOptions);
if (result.error?.status === Status.FORBIDDEN) {
store.dispatch(setForbidden(true));
return result;
}
// additional checks for auth_token and refresh_token logic
return result;
};
return fn;
};
Packages versions
- "@reduxjs/toolkit": "^1.7.2",
- "react-redux": "^7.2.6",