Reputation: 1578
I am using this solution https://redux-toolkit.js.org/rtk-query/usage/customizing-queries#automatic-re-authorization-by-extending-fetchbasequery to write reAuth baseQuery.
However I have multiple backend services with different createAPI services consume same refresh token concept.
Is there any way to have one baseQueryAuth can be used for multiple createApis
for example
productQuery.tsx
const baseQueryWithReauth: BaseQueryFn<
string | FetchArgs,
unknown,
FetchBaseQueryError
> = async (args, api, extraOptions) => {
let result = await baseQuery(args, api, extraOptions)
if (result.error && result.error.status === 401) {
// reset token
}
return result
}
/** Product Query **/
const baseQuery = fetchBaseQuery({
baseUrl: process.env.REACT_APP_PRODUCT_URL,
prepareHeaders: (headers) => {
headers.set('Authorization', `Bearer ${token}`);
return headers;
},
});
const productAPI = createApi({
reducerPath: 'productAPI',
baseQuery: baseQueryWithReauth,
endpoints: (builder) => {
...
...
}
})
On customerQuery.tsx
const baseQueryWithReauth: BaseQueryFn<
string | FetchArgs,
unknown,
FetchBaseQueryError
> = async (args, api, extraOptions) => {
let result = await baseQuery(args, api, extraOptions)
if (result.error && result.error.status === 401) {
// reset token
}
return result
}
/** Customer Query **/
const baseQuery = fetchBaseQuery({
baseUrl: process.env.REACT_APP_CUSTOMER_URL,
prepareHeaders: (headers) => {
headers.set('Authorization', `Bearer ${token}`);
return headers;
},
});
const customerAPI = createApi({
reducerPath: 'customerAPI',
baseQuery: baseQueryWithReauth,
endpoints: (builder) => {
...
...
}
})
Is there any way I can move the baseQueryWithReauth outside as one function and pass/bind the baseQuery based on different API?
Upvotes: 5
Views: 2827
Reputation: 20815
Yes, you can create a higher order function with currying, baseQueryWithReauth
will be a function that receives a baseQuery function as an argument and returns another baseQuery function
import { fetchBaseQuery } from "@reduxjs/toolkit/query";
import { createApi } from '@reduxjs/toolkit/query'
...
type BaseQueryType = ReturnType<typeof fetchBaseQuery>;
const baseQueryWithReauth: (baseQuery: BaseQueryType) => BaseQueryType = (
baseQuery
) => async (args, api, extraOptions) => {
let result = await baseQuery(args, api, extraOptions)
if (result.error && result.error.status === 401) {
// reset token
}
return result
}
and then use it to build each API
const productBaseQuery = fetchBaseQuery({
baseUrl: process.env.REACT_APP_PRODUCT_URL,
prepareHeaders: (headers) => {
headers.set('Authorization', `Bearer ${token}`);
return headers;
},
});
const productAPI = createApi({
reducerPath: "customerAPI",
baseQuery: baseQueryWithReauth(productBaseQuery),
endpoints: (builder) => {
...
},
});
const customerBaseQuery = fetchBaseQuery({
baseUrl: process.env.REACT_APP_CUSTOMER_URL,
prepareHeaders: (headers) => {
headers.set("Authorization", `Bearer ${token}`);
return headers;
},
});
const customerAPI = createApi({
reducerPath: "customerAPI",
baseQuery: baseQueryWithReauth(customerBaseQuery),
endpoints: (builder) => {
...
},
});
here is a sandbox for reference
https://codesandbox.io/s/hof-redux-toolkit-api-dlel1g?file=/src/api.ts
Upvotes: 9