RTK Query: Correct Store Configuration for Code Splitting? #2506
-
Hello, I am a mobile developer who has greatly enjoyed using RTK-Query. As I scale this particular application, I will employ the use of code splitting. However, I want to ensure that I am configuring the store correctly so that I continue to make the most out of the caching and fetching optimization that RTK-Query provides. If I initialize an empty api similar to the one in the docs, while extending the empty with additional user and posts endpoints, how should I properly configure the redux store? Additionally, would someone be able to provide reasoning as to why it should be configured this way to help my own understanding of RTK Query's under-the-hood operations? Thank you! Here is my current configuration for store.ts. import { configureStore } from '@reduxjs/toolkit'
import { setupListeners } from '@reduxjs/toolkit/query'
import { emptySplitApi } from './services/empty-api'
export const store = configureStore({
reducer: {
/*
I added the reducer path to the empty api, but was debating about adding the other apis instead here like:
[userApi.reducerPath]: emptySplitApi.reducer,
[postsApi.reducerPath]: emptySplitApi.reducer,
*/
[emptySplitApi.reducerPath]: emptySplitApi.reducer,
},
middleware: (getDefaultMiddleware) =>
/*
Referenced this stack overflow post to only concat the empty api middleware: https://stackoverflow.com/questions/71466817/splitting-api-definitions-with-rtk-query
But how do the injected endpoints know to use this cache memory?
*/
getDefaultMiddleware().concat(emptySplitApi.middleware),
}) Here is the definition of my APIs, if more context is needed. empty-api.ts import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react'
// initialize an empty api service that we'll inject endpoints into later as needed
export const emptySplitApi = createApi({
baseQuery: fetchBaseQuery({ baseUrl: '/' }),
endpoints: () => ({}),
}) user-api.ts import { emptySplitApi } from './emptySplitApi';
const userApi = emptySplitApi.injectEndpoints({
endpoints: (build) => ({
...
}),
});
export const { useGetUserQuery } = userApi; posts-api.ts import { emptySplitApi } from './emptySplitApi';
const postsApi = emptySplitApi.injectEndpoints({
endpoints: (build) => ({
...
})
});
export const { useGetPostsQuery } = postsApi; |
Beta Was this translation helpful? Give feedback.
Replies: 4 comments 2 replies
-
Per our docs, there should only be one "API slice" in the app (ie, a single call to Note that when you do something like So, for the store setup, you add the one API cache reducer and one API middleware to the store, and that's all you need to do. |
Beta Was this translation helpful? Give feedback.
-
Is it possible to inject endpoints from |
Beta Was this translation helpful? Give feedback.
-
Would it make sense to add this to the documentation on code splitting? @markerikson 👍 |
Beta Was this translation helpful? Give feedback.
-
What if you want to persist one of the API injections for example export const navAidsApi = baseApiSlice
.enhanceEndpoints({ addTagTypes: [CACHE_TAGS.NavAidsList] })
.injectEndpoints({
endpoints: (builder) => ({
getNavAidList: builder.query<NavAidsResponse, NavAidsQueryParams>({
query: (mapRegion) => ({
url: 'api/v1/navigational_aids',
method: APIMethods.GET,
params: getSwNeCoords(mapRegion),
}),
providesTags,
transformResponse(response) {
return response.data;
},
}),
addNavAid: builder.mutation({
query: (body) => ({
url: 'api/v1/navigational_aids',
method: APIMethods.POST,
body,
}),
invalidatesTags: [CACHE_TAGS.NavAidsList],
}),
updateNavAid: builder.mutation({
query: ({ id, ...body }) => ({
url: `api/v1/navigational_aids/${id}`,
method: APIMethods.PUT,
body,
}),
invalidatesTags: (_, __, { id }) => [
{ type: CACHE_TAGS.NavAidsList, id },
],
}),
deleteNavAid: builder.mutation<
{ status: string; message: string },
number
>({
query: (id) => ({
url: `api/v1/navigational_aids/${id}`,
method: APIMethods.DELETE,
}),
invalidatesTags: (_, __, id) => [{ type: CACHE_TAGS.NavAidsList, id }],
}),
}),
}); |
Beta Was this translation helpful? Give feedback.
Per our docs, there should only be one "API slice" in the app (ie, a single call to
createApi
).Note that when you do something like
const usersApi = emptySplitApi.injectEndpoints()
, it actually returns the sameapi
object reference - injecting the endpoints mutates that API object. That means that there won't be, say, ausersApi.reducer
, because there really is nousersApi
object - justemptySplitApi
, which will later have the users-related endpoints added to it.So, for the store setup, you add the one API cache reducer and one API middleware to the store, and that's all you need to do.