Generated API Slices
API Slice Overview
When you call createApi
, it automatically generates and returns an API service "slice" object structure containing Redux logic you can use to interact with the endpoints you defined. This slice object includes a reducer to manage cached data, a middleware to manage cache lifetimes and subscriptions, and selectors and thunks for each endpoint. If you imported createApi
from the React-specific entry point, it also includes auto-generated React hooks for use in your components.
This section documents the contents of that API structure, with the different fields grouped by category. The API types and descriptions are listed on separate pages for each category.
Typically, you should only have one API slice per base URL that your application needs to communicate with. For example, if your site fetches data from both /api/posts
and /api/users
, you would have a single API slice with /api/
as the base URL, and separate endpoint definitions for posts
and users
. This allows you to effectively take advantage of automated re-fetching by defining tag relationships across endpoints.
This is because:
- Automatic tag invalidation only works within a single API slice. If you have multiple API slices, the automatic invalidation won't work across them.
- Every
createApi
call generates its own middleware, and each middleware added to the store will run checks against every dispatched action. That has a perf cost that adds up. So, if you calledcreateApi
10 times and added 10 separate API middleware to the store, that will be noticeably slower perf-wise.
For maintainability purposes, you may wish to split up endpoint definitions across multiple files, while still maintaining a single API slice which includes all of these endpoints. See code splitting for how you can use the injectEndpoints
property to inject API endpoints from other files into a single API slice definition.
const api = createApi({
baseQuery: fetchBaseQuery({ baseUrl: '/' }),
endpoints: (build) => ({
// ...
}),
})
type Api = {
// Redux integration
reducerPath: string
reducer: Reducer
middleware: Middleware
// Endpoint interactions
endpoints: Record<string, EndpointDefinition>
// Code splitting and generation
injectEndpoints: (options: InjectEndpointsOptions) => UpdatedApi
enhanceEndpoints: (options: EnhanceEndpointsOptions) => UpdatedApi
// Utilities
utils: {
updateQueryData: UpdateQueryDataThunk
patchQueryData: PatchQueryDataThunk
prefetch: PrefetchThunk
invalidateTags: ActionCreatorWithPayload<
Array<TagTypes | FullTagDescription<TagTypes>>,
string
>
selectInvalidatedBy: (
state: FullState,
tags: Array<TagTypes | FullTagDescription<TagTypes>>,
) => Array<{
endpointName: string
originalArgs: any
queryCacheKey: string
}>
selectCachedArgsForQuery: (
state: FullState,
endpointName: EndpointName,
) => Array<QueryArg>
resetApiState: ActionCreator<ResetAction>
getRunningQueryThunk(
endpointName: EndpointName,
args: QueryArg,
): ThunkWithReturnValue<QueryActionCreatorResult | undefined>
getRunningMutationThunk(
endpointName: EndpointName,
fixedCacheKeyOrRequestId: string,
): ThunkWithReturnValue<MutationActionCreatorResult | undefined>
getRunningQueriesThunk(): ThunkWithReturnValue<
Array<QueryActionCreatorResult<any>>
>
getRunningMutationsThunk(): ThunkWithReturnValue<
Array<MutationActionCreatorResult<any>>
>
}
// Internal actions
internalActions: InternalActions
// React hooks (if applicable)
[key in GeneratedReactHooks]: GeneratedReactHooks[key]
}
Redux Integration
Internally, createApi
will call the Redux Toolkit createSlice
API to generate a slice reducer and corresponding action creators with the appropriate logic for caching fetched data. It also automatically generates a custom Redux middleware that manages subscription counts and cache lifetimes.
The generated slice reducer and the middleware both need to be adding to your Redux store setup in configureStore
in order to work correctly.
Endpoints
The API slice object will have an endpoints
field inside. This section maps the endpoint names you provided to createApi
to the core Redux logic (thunks and selectors) used to trigger data fetches and read cached data for that endpoint. If you're using the React-specific version of createApi
, each endpoint definition will also contain the auto-generated React hooks for that endpoint.
Code Splitting and Generation
Each API slice allows additional endpoint definitions to be injected at runtime after the initial API slice has been defined. This can be beneficial for apps that may have many endpoints.
The individual API slice endpoint definitions can also be split across multiple files. This is primarily useful for working with API slices that were code-generated from an API schema file, allowing you to add additional custom behavior and configuration to a set of automatically-generated endpoint definitions.
Each API slice object has injectEndpoints
and enhanceEndpoints
functions to support these use cases.
API Slice Utilities
The util
field includes various utility functions that can be used to manage the cache, including
manually updating query cache data, triggering pre-fetching of data, manually invalidating tags,
and manually resetting the api state, as well as other utility functions that can be used in
various scenarios, including SSR.
Internal Actions
The internalActions
field contains a set of additional thunks that are used for internal behavior, such as managing updates based on focus.
React Hooks
The core RTK Query createApi
method is UI-agnostic, in the same way that the Redux core library and Redux Toolkit are UI-agnostic. They are all plain JS logic that can be used anywhere.
However, RTK Query also provides the ability to auto-generate React hooks for each of your endpoints. Since this specifically depends on React itself, RTK Query provides an alternate entry point that exposes a customized version of createApi
that includes that functionality:
import { createApi } from '@reduxjs/toolkit/query/react'
If you have used the React-specific version of createApi
, the generated Api
slice structure will also contain a set of React hooks. These endpoint hooks are available as api.endpoints[endpointName].useQuery
or api.endpoints[endpointName].useMutation
, matching how you defined that endpoint.
The same hooks are also added to the Api
object itself, and given auto-generated names based on the endpoint name and query/mutation type.
For example, if you had endpoints for getPosts
and updatePost
, these options would be available:
// Hooks attached to the endpoint definition
const { data } = api.endpoints.getPosts.useQuery()
const { data } = api.endpoints.updatePost.useMutation()
// Same hooks, but given unique names and attached to the API slice object
const { data } = api.useGetPostsQuery()
const [updatePost] = api.useUpdatePostMutation()
The React-specific version of createApi
also generates a usePrefetch
hook, attached to the Api
object, which can be used to initiate fetching data ahead of time.