A RetroSearch Logo

Home - News ( United States | United Kingdom | Italy | Germany ) - Football scores

Search Query:

Showing content from https://redux-toolkit.js.org/rtk-query/api/createApi below:

createApi | Redux Toolkit

createApi

createApi is the core of RTK Query's functionality. It allows you to define a set of "endpoints" that describe how to retrieve data from backend APIs and other async sources, including the configuration of how to fetch and transform that data. It generates an "API slice" structure that contains Redux logic (and optionally React hooks) that encapsulate the data fetching and caching process for you.

tip

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:

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.

Example: src/services/pokemon.ts


import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react'
import type { Pokemon } from './types'


export const pokemonApi = createApi({
reducerPath: 'pokemonApi',
baseQuery: fetchBaseQuery({ baseUrl: 'https://pokeapi.co/api/v2/' }),
endpoints: (build) => ({
getPokemonByName: build.query<Pokemon, string>({
query: (name) => `pokemon/${name}`,
}),
}),
})



export const { useGetPokemonByNameQuery } = pokemonApi

Example: src/services/pokemon.js


import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react'


export const pokemonApi = createApi({
reducerPath: 'pokemonApi',
baseQuery: fetchBaseQuery({ baseUrl: 'https://pokeapi.co/api/v2/' }),
endpoints: (build) => ({
getPokemonByName: build.query({
query: (name) => `pokemon/${name}`,
}),
}),
})



export const { useGetPokemonByNameQuery } = pokemonApi
createApi Parameters

createApi accepts a single configuration object parameter with the following options:

  baseQuery(args: InternalQueryArgs, api: BaseQueryApi, extraOptions?: DefinitionExtraOptions): any;
endpoints(build: EndpointBuilder<InternalQueryArgs, TagTypes>): Definitions;
extractRehydrationInfo?: (
action: UnknownAction,
{
reducerPath,
}: {
reducerPath: ReducerPath
}
) =>
| undefined
| CombinedState<Definitions, TagTypes, ReducerPath>
tagTypes?: readonly TagTypes[];
reducerPath?: ReducerPath;
serializeQueryArgs?: SerializeQueryArgs<InternalQueryArgs>;
keepUnusedDataFor?: number;
refetchOnMountOrArgChange?: boolean | number;
refetchOnFocus?: boolean;
refetchOnReconnect?: boolean;
baseQuery

The base query used by each endpoint if no queryFn option is specified. RTK Query exports a utility called fetchBaseQuery as a lightweight wrapper around fetch for common use-cases. See Customizing Queries if fetchBaseQuery does not handle your requirements.

baseQuery function arguments baseQuery function signature

Base Query signature

export type BaseQueryFn<
Args = any,
Result = unknown,
Error = unknown,
DefinitionExtraOptions = {},
Meta = {},
> = (
args: Args,
api: BaseQueryApi,
extraOptions: DefinitionExtraOptions,
) => MaybePromise<QueryReturnValue<Result, Error, Meta>>

export interface BaseQueryApi {
signal: AbortSignal
abort: (reason?: string) => void
dispatch: ThunkDispatch<any, any, any>
getState: () => unknown
extra: unknown
endpoint: string
type: 'query' | 'mutation'
forced?: boolean
}

export type QueryReturnValue<T = unknown, E = unknown, M = unknown> =
| {
error: E
data?: undefined
meta?: M
}
| {
error?: undefined
data: T
meta?: M
}
import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query'

const api = createApi({
baseQuery: fetchBaseQuery({ baseUrl: '/' }),
endpoints: (build) => ({

}),
})
import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query'

const api = createApi({
baseQuery: fetchBaseQuery({ baseUrl: '/' }),
endpoints: (build) => ({

}),
})
endpoints

Endpoints are a set of operations that you want to perform against your server. You define them as an object using the builder syntax. There are three endpoint types: query, infiniteQuery and mutation.

See Endpoint Definition Parameters for details on individual properties.

Query endpoint definition

Query endpoints (defined with build.query()) are used to cache data fetched from the server.

You must specify either a query field (which will use the API's baseQuery to make a request), or a queryFn function with your own async logic. All other fields are optional.

Query endpoint definition

export type FullTagDescription<TagType> = {
type: TagType
id?: number | string
}
export type TagDescription<TagType> = TagType | FullTagDescription<TagType>

type TagDescriptionArray<TagTypes extends string> = ReadonlyArray<
TagDescription<TagTypes> | undefined | null
>

export type ResultDescription<
TagTypes extends string,
ResultType,
QueryArg,
ErrorType,
MetaType,
> =
| TagDescriptionArray<TagTypes>
| (
result: ResultType | undefined,
error: ErrorType | undefined,
arg: QueryArg,
meta: MetaType,
) => TagDescriptionArray<TagTypes>


export type QueryDefinition<
QueryArg,
BaseQuery extends BaseQueryFn,
TagTypes extends string,
ResultType,
ReducerPath extends string = string,
> = {
query(arg: QueryArg): BaseQueryArg<BaseQuery>


queryFn(
arg: QueryArg,
api: BaseQueryApi,
extraOptions: BaseQueryExtraOptions<BaseQuery>,
baseQuery: (arg: Parameters<BaseQuery>[0]) => ReturnType<BaseQuery>,
): MaybePromise<QueryReturnValue<ResultType, BaseQueryError<BaseQuery>>>


transformResponse?(
baseQueryReturnValue: BaseQueryResult<BaseQuery>,
meta: BaseQueryMeta<BaseQuery>,
arg: QueryArg,
): ResultType | Promise<ResultType>


transformErrorResponse?(
baseQueryReturnValue: BaseQueryError<BaseQuery>,
meta: BaseQueryMeta<BaseQuery>,
arg: QueryArg,
): unknown

extraOptions?: BaseQueryExtraOptions<BaseQuery>

providesTags?: ResultDescription<
TagTypes,
ResultType,
QueryArg,
BaseQueryError<BaseQuery>
>

keepUnusedDataFor?: number

onQueryStarted?(
arg: QueryArg,
{
dispatch,
getState,
extra,
requestId,
queryFulfilled,
getCacheEntry,
updateCachedData,
}: QueryLifecycleApi,
): Promise<void>

onCacheEntryAdded?(
arg: QueryArg,
{
dispatch,
getState,
extra,
requestId,
cacheEntryRemoved,
cacheDataLoaded,
getCacheEntry,
updateCachedData,
}: QueryCacheLifecycleApi,
): Promise<void>

argSchema?: StandardSchemaV1<QueryArg>


rawResponseSchema?: StandardSchemaV1<BaseQueryResult<BaseQuery>>

responseSchema?: StandardSchemaV1<ResultType>


rawErrorResponseSchema?: StandardSchemaV1<BaseQueryError<BaseQuery>>

errorResponseSchema?: StandardSchemaV1<BaseQueryError<BaseQuery>>

metaSchema?: StandardSchemaV1<BaseQueryMeta<BaseQuery>>
}
Infinite Query endpoint definition

Infinite query endpoints (defined with build.infiniteQuery()) are used to cache multi-page data sets from the server. They have all the same callbacks and options as standard query endpoints, but also require an additional infiniteQueryOptions field to specify how to calculate the unique parameters to fetch each page.

For infinite query endpoints, there is a separation between the "query arg" used for the cache key, and the "page param" used to fetch a specific page. For example, a Pokemon API endpoint might have a string query arg like "fire" , but use a page number as the param to determine which page to fetch out of the results. The query and queryFn methods will receive a combined {queryArg, pageParam} object as the argument, rather than just the queryArg by itself.

Infinite Query endpoint definition

export type PageParamFunction<DataType, PageParam, QueryArg> = (
firstPage: DataType,
allPages: Array<DataType>,
firstPageParam: PageParam,
allPageParams: Array<PageParam>,
queryArg: QueryArg,
) => PageParam | undefined | null

type InfiniteQueryCombinedArg<QueryArg, PageParam> = {
queryArg: QueryArg
pageParam: PageParam
}

export type InfiniteQueryDefinition<
QueryArg,
PageParam,
BaseQuery extends BaseQueryFn,
TagTypes extends string,
ResultType,
ReducerPath extends string = string,
> =



QueryDefinition<
InfiniteQueryCombinedArg<QueryArg, PageParam>,
BaseQuery,
TagTypes,
InfiniteData<ResultType>
> & {







infiniteQueryOptions: {



initialPageParam: PageParam




getNextPageParam: PageParamFunction<DataType, PageParam, QueryArg>




getPreviousPageParam?: PageParamFunction<DataType, PageParam, QueryArg>





maxPages?: number
}
}
Mutation endpoint definition

Mutation endpoints (defined with build.mutation()) are used to send updates to the server, and force invalidation and refetching of query endpoints.

As with queries, you must specify either the query option or the queryFn async method.

Mutation endpoint definition

export type MutationDefinition<
QueryArg,
BaseQuery extends BaseQueryFn,
TagTypes extends string,
ResultType,
ReducerPath extends string = string,
Context = Record<string, any>,
> = {
query(arg: QueryArg): BaseQueryArg<BaseQuery>


queryFn(
arg: QueryArg,
api: BaseQueryApi,
extraOptions: BaseQueryExtraOptions<BaseQuery>,
baseQuery: (arg: Parameters<BaseQuery>[0]) => ReturnType<BaseQuery>,
): MaybePromise<QueryReturnValue<ResultType, BaseQueryError<BaseQuery>>>


transformResponse?(
baseQueryReturnValue: BaseQueryResult<BaseQuery>,
meta: BaseQueryMeta<BaseQuery>,
arg: QueryArg,
): ResultType | Promise<ResultType>


transformErrorResponse?(
baseQueryReturnValue: BaseQueryError<BaseQuery>,
meta: BaseQueryMeta<BaseQuery>,
arg: QueryArg,
): unknown

extraOptions?: BaseQueryExtraOptions<BaseQuery>

invalidatesTags?: ResultDescription<TagTypes, ResultType, QueryArg>

onQueryStarted?(
arg: QueryArg,
{
dispatch,
getState,
extra,
requestId,
queryFulfilled,
getCacheEntry,
}: MutationLifecycleApi,
): Promise<void>

onCacheEntryAdded?(
arg: QueryArg,
{
dispatch,
getState,
extra,
requestId,
cacheEntryRemoved,
cacheDataLoaded,
getCacheEntry,
}: MutationCacheLifecycleApi,
): Promise<void>
}
How endpoints get used

When defining a key like getPosts as shown below, it's important to know that this name will become exportable from api and be able to referenced under api.endpoints.getPosts.useQuery(), api.endpoints.getPosts.initiate() and api.endpoints.getPosts.select(). The same thing applies to mutations but they reference useMutation instead of useQuery.

import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react'
interface Post {
id: number
name: string
}
type PostsResponse = Post[]

const api = createApi({
baseQuery: fetchBaseQuery({ baseUrl: '/' }),
tagTypes: ['Posts'],
endpoints: (build) => ({
getPosts: build.query<PostsResponse, void>({
query: () => 'posts',
providesTags: (result) =>
result ? result.map(({ id }) => ({ type: 'Posts', id })) : [],
}),
addPost: build.mutation<Post, Partial<Post>>({
query: (body) => ({
url: `posts`,
method: 'POST',
body,
}),
invalidatesTags: ['Posts'],
}),
}),
})


export const { useGetPostsQuery, useAddPostMutation } = api


export const { endpoints, reducerPath, reducer, middleware } = api





import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react'

const api = createApi({
baseQuery: fetchBaseQuery({ baseUrl: '/' }),
tagTypes: ['Posts'],
endpoints: (build) => ({
getPosts: build.query({
query: () => 'posts',
providesTags: (result) =>
result ? result.map(({ id }) => ({ type: 'Posts', id })) : [],
}),
addPost: build.mutation({
query: (body) => ({
url: `posts`,
method: 'POST',
body,
}),
invalidatesTags: ['Posts'],
}),
}),
})


export const { useGetPostsQuery, useAddPostMutation } = api


export const { endpoints, reducerPath, reducer, middleware } = api





A function that is passed every dispatched action. If this returns something other than undefined, that return value will be used to rehydrate fulfilled & errored queries.

next-redux-wrapper rehydration example

import type { Action, PayloadAction } from '@reduxjs/toolkit'
import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react'
import { HYDRATE } from 'next-redux-wrapper'

type RootState = any

function isHydrateAction(action: Action): action is PayloadAction<RootState> {
return action.type === HYDRATE
}

export const api = createApi({
baseQuery: fetchBaseQuery({ baseUrl: '/' }),
extractRehydrationInfo(action, { reducerPath }): any {
if (isHydrateAction(action)) {
return action.payload[reducerPath]
}
},
endpoints: (build) => ({

}),
})

next-redux-wrapper rehydration example

import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react'
import { HYDRATE } from 'next-redux-wrapper'

function isHydrateAction(action) {
return action.type === HYDRATE
}

export const api = createApi({
baseQuery: fetchBaseQuery({ baseUrl: '/' }),
extractRehydrationInfo(action, { reducerPath }) {
if (isHydrateAction(action)) {
return action.payload[reducerPath]
}
},
endpoints: (build) => ({

}),
})

See also Server Side Rendering and Persistence and Rehydration.

tagTypes

An array of string tag type names. Specifying tag types is optional, but you should define them so that they can be used for caching and invalidation. When defining a tag type, you will be able to provide them with providesTags and invalidate them with invalidatesTags when configuring endpoints.

import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query'

const api = createApi({
baseQuery: fetchBaseQuery({ baseUrl: '/' }),
tagTypes: ['Post', 'User'],
endpoints: (build) => ({

}),
})
import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query'

const api = createApi({
baseQuery: fetchBaseQuery({ baseUrl: '/' }),
tagTypes: ['Post', 'User'],
endpoints: (build) => ({

}),
})
reducerPath

The reducerPath is a unique key that your service will be mounted to in your store. If you call createApi more than once in your application, you will need to provide a unique value each time. Defaults to 'api'.

apis.js

import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query'

const apiOne = createApi({
reducerPath: 'apiOne',
baseQuery: fetchBaseQuery({ baseUrl: '/' }),
endpoints: (builder) => ({

}),
})

const apiTwo = createApi({
reducerPath: 'apiTwo',
baseQuery: fetchBaseQuery({ baseUrl: '/' }),
endpoints: (builder) => ({

}),
})

apis.js

import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query'

const apiOne = createApi({
reducerPath: 'apiOne',
baseQuery: fetchBaseQuery({ baseUrl: '/' }),
endpoints: (builder) => ({

}),
})

const apiTwo = createApi({
reducerPath: 'apiTwo',
baseQuery: fetchBaseQuery({ baseUrl: '/' }),
endpoints: (builder) => ({

}),
})
serializeQueryArgs

Accepts a custom function if you have a need to change the creation of cache keys for any reason.

By default, this function will take the query arguments, sort object keys where applicable, stringify the result, and concatenate it with the endpoint name. This creates a cache key based on the combination of arguments + endpoint name (ignoring object key order), such that calling any given endpoint with the same arguments will result in the same cache key.

invalidationBehavior

Defaults to 'delayed'. This setting allows you to control when tags are invalidated after a mutation.

keepUnusedDataFor

Defaults to 60 (this value is in seconds). This is how long RTK Query will keep your data cached for after the last component unsubscribes. For example, if you query an endpoint, then unmount the component, then mount another component that makes the same request within the given time frame, the most recent value will be served from the cache.

keepUnusedDataFor example

import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react'
interface Post {
id: number
name: string
}
type PostsResponse = Post[]

const api = createApi({
baseQuery: fetchBaseQuery({ baseUrl: '/' }),
endpoints: (build) => ({
getPosts: build.query<PostsResponse, void>({
query: () => 'posts',
keepUnusedDataFor: 5,
}),
}),
})

keepUnusedDataFor example

import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react'

const api = createApi({
baseQuery: fetchBaseQuery({ baseUrl: '/' }),
endpoints: (build) => ({
getPosts: build.query({
query: () => 'posts',
keepUnusedDataFor: 5,
}),
}),
})
refetchOnMountOrArgChange

Defaults to false. This setting allows you to control whether if a cached result is already available RTK Query will only serve a cached result, or if it should refetch when set to true or if an adequate amount of time has passed since the last successful query result.

If you specify this option alongside skip: true, this will not be evaluated until skip is false.

note

You can set this globally in createApi, but you can also override the default value and have more granular control by passing refetchOnMountOrArgChange to each individual hook call or similarly by passing forceRefetch: true when dispatching the initiate action.

refetchOnFocus

Defaults to false. This setting allows you to control whether RTK Query will try to refetch all subscribed queries after the application window regains focus.

If you specify this option alongside skip: true, this will not be evaluated until skip is false.

Note: requires setupListeners to have been called.

note

You can set this globally in createApi, but you can also override the default value and have more granular control by passing refetchOnFocus to each individual hook call or when dispatching the initiate action.

If you specify track: false when manually dispatching queries, RTK Query will not be able to automatically refetch for you.

refetchOnReconnect

Defaults to false. This setting allows you to control whether RTK Query will try to refetch all subscribed queries after regaining a network connection.

If you specify this option alongside skip: true, this will not be evaluated until skip is false.

Note: requires setupListeners to have been called.

note

You can set this globally in createApi, but you can also override the default value and have more granular control by passing refetchOnReconnect to each individual hook call or when dispatching the initiate action.

If you specify track: false when manually dispatching queries, RTK Query will not be able to automatically refetch for you.

onSchemaFailure

A function that is called when a schema validation fails.

Gets called with a NamedSchemaError and an object containing the endpoint name, the type of the endpoint, the argument passed to the endpoint, and the query cache key (if applicable).

NamedSchemaError has the following properties:

import { createApi } from '@reduxjs/toolkit/query/react'
import * as v from "valibot"

const api = createApi({
baseQuery: fetchBaseQuery({ baseUrl: '/' }),
endpoints: (build) => ({
getPost: build.query<Post, { id: number }>({
query: ({ id }) => `/post/${id}`,
}),
}),
onSchemaFailure: (error, info) => {
console.error(error, info)
},
})

note

You can set this globally in createApi, but you can also override the default value and have more granular control by passing onSchemaFailure to each individual endpoint definition.

catchSchemaFailure

Convert a schema validation failure into an error shape matching base query errors.

When not provided, schema failures are treated as fatal, and normal error handling such as tag invalidation will not be executed.

import { createApi } from '@reduxjs/toolkit/query/react'
import * as v from "valibot"

const api = createApi({
baseQuery: fetchBaseQuery({ baseUrl: '/' }),
endpoints: (build) => ({
getPost: build.query<Post, { id: number }>({
query: ({ id }) => `/post/${id}`,
responseSchema: v.object({ id: v.number(), name: v.string() }),
}),
}),
catchSchemaFailure: (error, info) => ({
status: "CUSTOM_ERROR",
error: error.schemaName + " failed validation",
data: error.issues,
}),
})

note

You can set this globally in createApi, but you can also override the default value and have more granular control by passing catchSchemaFailure to each individual endpoint definition.

skipSchemaValidation

Defaults to false.

If set to true, will skip schema validation for all endpoints, unless overridden by the endpoint.

Can be overridden for specific schemas by passing an array of schema types to skip.

import { createApi } from '@reduxjs/toolkit/query/react'
import * as v from "valibot"

const api = createApi({
baseQuery: fetchBaseQuery({ baseUrl: '/' }),
skipSchemaValidation: process.env.NODE_ENV === "test" ? ["response"] : false,
endpoints: (build) => ({
getPost: build.query<Post, { id: number }>({
query: ({ id }) => `/post/${id}`,
responseSchema: v.object({ id: v.number(), name: v.string() }),
}),
})
})

note

You can set this globally in createApi, but you can also override the default value and have more granular control by passing skipSchemaValidation to each individual endpoint definition.

Endpoint Definition Parameters query

(required if no queryFn provided)

query signature

export type query = <QueryArg>(
arg: QueryArg,
) => string | Record<string, unknown>


export type query = <QueryArg>(arg: QueryArg) => string | FetchArgs
queryFn

(required if no query provided)

Called with the same arguments as baseQuery, as well as the provided baseQuery function itself. It is expected to return an object with either a data or error property, or a promise that resolves to return such an object.

See also Customizing queries with queryFn.

queryFn signature

queryFn(
arg: QueryArg,
api: BaseQueryApi,
extraOptions: BaseQueryExtraOptions<BaseQuery>,
baseQuery: (arg: Parameters<BaseQuery>[0]) => ReturnType<BaseQuery>
): MaybePromise<
| {
error: BaseQueryError<BaseQuery>
data?: undefined
}
| {
error?: undefined
data: ResultType
}
>

export interface BaseQueryApi {
signal: AbortSignal
dispatch: ThunkDispatch<any, any, any>
getState: () => unknown
}
queryFn function arguments infiniteQueryOptions

(only for infiniteQuery endpoints)

Required options to configure the infinite query behavior. initialPageParam and getNextPageParam are required, to ensure the infinite query can properly fetch the next page of data. initialPageParam may be specified when using the endpoint, to override the default value. maxPages and getPreviousPageParam are both optional.

The infiniteQueryOptions field includes:

infiniteQueryOptions example

import {
createApi,
fetchBaseQuery,
defaultSerializeQueryArgs,
} from '@reduxjs/toolkit/query/react'

type Pokemon = {
id: string
name: string
}

const pokemonApi = createApi({
baseQuery: fetchBaseQuery({ baseUrl: 'https://pokeapi.co/api/v2/' }),
endpoints: (build) => ({
getInfinitePokemonWithMax: build.infiniteQuery<Pokemon[], string, number>({
infiniteQueryOptions: {
initialPageParam: 0,
maxPages: 3,
getNextPageParam: (lastPage, allPages, lastPageParam, allPageParams) =>
lastPageParam + 1,
getPreviousPageParam: (
firstPage,
allPages,
firstPageParam,
allPageParams,
) => {
return firstPageParam > 0 ? firstPageParam - 1 : undefined
},
},
query({ pageParam }) {
return `https://example.com/listItems?page=${pageParam}`
},
}),
}),
})

infiniteQueryOptions example

import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react'

const pokemonApi = createApi({
baseQuery: fetchBaseQuery({ baseUrl: 'https://pokeapi.co/api/v2/' }),
endpoints: (build) => ({
getInfinitePokemonWithMax: build.infiniteQuery({
infiniteQueryOptions: {
initialPageParam: 0,
maxPages: 3,
getNextPageParam: (lastPage, allPages, lastPageParam, allPageParams) =>
lastPageParam + 1,
getPreviousPageParam: (
firstPage,
allPages,
firstPageParam,
allPageParams,
) => {
return firstPageParam > 0 ? firstPageParam - 1 : undefined
},
},
query({ pageParam }) {
return `https://example.com/listItems?page=${pageParam}`
},
}),
}),
})
transformResponse

(optional, not applicable with queryFn)

In some cases, you may want to manipulate the data returned from a query before you put it in the cache. In this instance, you can take advantage of transformResponse.

See also Customizing query responses with transformResponse

Unpack a deeply nested collection

transformResponse: (response, meta, arg) =>
response.some.deeply.nested.collection
transformErrorResponse

(optional, not applicable with queryFn)

In some cases, you may want to manipulate the error returned from a query before you put it in the cache. In this instance, you can take advantage of transformErrorResponse.

See also Customizing query responses with transformErrorResponse

Unpack a deeply nested error object

transformErrorResponse: (response, meta, arg) =>
response.data.some.deeply.nested.errorObject

(optional)

Passed as the third argument to the supplied baseQuery function

providesTags

(optional, only for query endpoints)

Used by query endpoints. Determines which 'tag' is attached to the cached data returned by the query. Expects an array of tag type strings, an array of objects of tag types with ids, or a function that returns such an array.

  1. ['Post'] - equivalent to 2
  2. [{ type: 'Post' }] - equivalent to 1
  3. [{ type: 'Post', id: 1 }]
  4. (result, error, arg) => ['Post'] - equivalent to 5
  5. (result, error, arg) => [{ type: 'Post' }] - equivalent to 4
  6. (result, error, arg) => [{ type: 'Post', id: 1 }]

See also Providing cache data.

providesTags example

import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react'
interface Post {
id: number
name: string
}
type PostsResponse = Post[]

const api = createApi({
baseQuery: fetchBaseQuery({ baseUrl: '/' }),
tagTypes: ['Posts'],
endpoints: (build) => ({
getPosts: build.query<PostsResponse, void>({
query: () => 'posts',
providesTags: (result) =>
result
? [
...result.map(({ id }) => ({ type: 'Posts' as const, id })),
{ type: 'Posts', id: 'LIST' },
]
: [{ type: 'Posts', id: 'LIST' }],
}),
}),
})

providesTags example

import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react'

const api = createApi({
baseQuery: fetchBaseQuery({ baseUrl: '/' }),
tagTypes: ['Posts'],
endpoints: (build) => ({
getPosts: build.query({
query: () => 'posts',
providesTags: (result) =>
result
? [
...result.map(({ id }) => ({ type: 'Posts', id })),
{ type: 'Posts', id: 'LIST' },
]
: [{ type: 'Posts', id: 'LIST' }],
}),
}),
})
invalidatesTags

(optional, only for mutation endpoints)

Used by mutation endpoints. Determines which cached data should be either re-fetched or removed from the cache. Expects the same shapes as providesTags.

See also Invalidating cache data.

invalidatesTags example

import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react'
interface Post {
id: number
name: string
}
type PostsResponse = Post[]

const api = createApi({
baseQuery: fetchBaseQuery({ baseUrl: '/' }),
tagTypes: ['Posts'],
endpoints: (build) => ({
getPosts: build.query<PostsResponse, void>({
query: () => 'posts',
providesTags: (result) =>
result
? [
...result.map(({ id }) => ({ type: 'Posts' as const, id })),
{ type: 'Posts', id: 'LIST' },
]
: [{ type: 'Posts', id: 'LIST' }],
}),
addPost: build.mutation<Post, Partial<Post>>({
query(body) {
return {
url: `posts`,
method: 'POST',
body,
}
},
invalidatesTags: [{ type: 'Posts', id: 'LIST' }],
}),
}),
})

invalidatesTags example

import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react'

const api = createApi({
baseQuery: fetchBaseQuery({ baseUrl: '/' }),
tagTypes: ['Posts'],
endpoints: (build) => ({
getPosts: build.query({
query: () => 'posts',
providesTags: (result) =>
result
? [
...result.map(({ id }) => ({ type: 'Posts', id })),
{ type: 'Posts', id: 'LIST' },
]
: [{ type: 'Posts', id: 'LIST' }],
}),
addPost: build.mutation({
query(body) {
return {
url: `posts`,
method: 'POST',
body,
}
},
invalidatesTags: [{ type: 'Posts', id: 'LIST' }],
}),
}),
})
keepUnusedDataFor

(optional, only for query endpoints)

Overrides the api-wide definition of keepUnusedDataFor for this endpoint only.

Defaults to 60 (this value is in seconds). This is how long RTK Query will keep your data cached for after the last component unsubscribes. For example, if you query an endpoint, then unmount the component, then mount another component that makes the same request within the given time frame, the most recent value will be served from the cache.

keepUnusedDataFor example

import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react'
interface Post {
id: number
name: string
}
type PostsResponse = Post[]

const api = createApi({
baseQuery: fetchBaseQuery({ baseUrl: '/' }),
endpoints: (build) => ({
getPosts: build.query<PostsResponse, void>({
query: () => 'posts',
keepUnusedDataFor: 5,
}),
}),
})

keepUnusedDataFor example

import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react'

const api = createApi({
baseQuery: fetchBaseQuery({ baseUrl: '/' }),
endpoints: (build) => ({
getPosts: build.query({
query: () => 'posts',
keepUnusedDataFor: 5,
}),
}),
})
serializeQueryArgs

(optional, only for query endpoints)

Can be provided to return a custom cache key value based on the query arguments.

This is primarily intended for cases where a non-serializable value is passed as part of the query arg object and should be excluded from the cache key. It may also be used for cases where an endpoint should only have a single cache entry, such as an infinite loading / pagination implementation.

Unlike the createApi version which can only return a string, this per-endpoint option can also return an an object, number, or boolean. If it returns a string, that value will be used as the cache key directly. If it returns an object / number / boolean, that value will be passed to the built-in defaultSerializeQueryArgs. This simplifies the use case of stripping out args you don't want included in the cache key.

serializeQueryArgs : exclude value

import {
createApi,
fetchBaseQuery,
defaultSerializeQueryArgs,
} from '@reduxjs/toolkit/query/react'
interface Post {
id: number
name: string
}

interface MyApiClient {
fetchPost: (id: string) => Promise<Post>
}

createApi({
baseQuery: fetchBaseQuery({ baseUrl: '/' }),
endpoints: (build) => ({


getPost: build.query<Post, { id: string; client: MyApiClient }>({
queryFn: async ({ id, client }) => {
const post = await client.fetchPost(id)
return { data: post }
},
serializeQueryArgs: ({ queryArgs, endpointDefinition, endpointName }) => {
const { id } = queryArgs



return { id }









},
}),
}),
})

serializeQueryArgs : exclude value

import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react'

createApi({
baseQuery: fetchBaseQuery({ baseUrl: '/' }),
endpoints: (build) => ({


getPost: build.query({
queryFn: async ({ id, client }) => {
const post = await client.fetchPost(id)
return { data: post }
},
serializeQueryArgs: ({ queryArgs, endpointDefinition, endpointName }) => {
const { id } = queryArgs



return { id }









},
}),
}),
})
merge

(optional, only for query endpoints)

Can be provided to merge an incoming response value into the current cache data. If supplied, no automatic structural sharing will be applied - it's up to you to update the cache appropriately.

Since RTKQ normally replaces cache entries with the new response, you will usually need to use this with the serializeQueryArgs or forceRefetch options to keep an existing cache entry so that it can be updated.

Since this is wrapped with Immer, you may either mutate the currentCacheValue directly, or return a new value, but not both at once.

Will only be called if the existing currentCacheData is not undefined - on first response, the cache entry will just save the response data directly.

Useful if you don't want a new request to completely override the current cache value, maybe because you have manually updated it from another source and don't want those updates to get lost.

merge: pagination

import {
createApi,
fetchBaseQuery,
defaultSerializeQueryArgs,
} from '@reduxjs/toolkit/query/react'
interface Post {
id: number
name: string
}

createApi({
baseQuery: fetchBaseQuery({ baseUrl: '/' }),
endpoints: (build) => ({
listItems: build.query<string[], number>({
query: (pageNumber) => `/listItems?page=${pageNumber}`,

serializeQueryArgs: ({ endpointName }) => {
return endpointName
},

merge: (currentCache, newItems) => {
currentCache.push(...newItems)
},

forceRefetch({ currentArg, previousArg }) {
return currentArg !== previousArg
},
}),
}),
})

merge: pagination

import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react'

createApi({
baseQuery: fetchBaseQuery({ baseUrl: '/' }),
endpoints: (build) => ({
listItems: build.query({
query: (pageNumber) => `/listItems?page=${pageNumber}`,

serializeQueryArgs: ({ endpointName }) => {
return endpointName
},

merge: (currentCache, newItems) => {
currentCache.push(...newItems)
},

forceRefetch({ currentArg, previousArg }) {
return currentArg !== previousArg
},
}),
}),
})
forceRefetch

(optional, only for query endpoints)

forceRefetch signature

type forceRefetch = (params: {
currentArg: QueryArg | undefined
previousArg: QueryArg | undefined
state: RootState<any, any, string>
endpointState?: QuerySubState<any>
}) => boolean

Check to see if the endpoint should force a refetch in cases where it normally wouldn't. This is primarily useful for "infinite scroll" / pagination use cases where RTKQ is keeping a single cache entry that is added to over time, in combination with serializeQueryArgs returning a fixed cache key and a merge callback set to add incoming data to the cache entry each time.

forceRefresh: pagination

import {
createApi,
fetchBaseQuery,
defaultSerializeQueryArgs,
} from '@reduxjs/toolkit/query/react'
interface Post {
id: number
name: string
}

createApi({
baseQuery: fetchBaseQuery({ baseUrl: '/' }),
endpoints: (build) => ({
listItems: build.query<string[], number>({
query: (pageNumber) => `/listItems?page=${pageNumber}`,

serializeQueryArgs: ({ endpointName }) => {
return endpointName
},

merge: (currentCache, newItems) => {
currentCache.push(...newItems)
},

forceRefetch({ currentArg, previousArg }) {
return currentArg !== previousArg
},
}),
}),
})

forceRefresh: pagination

import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react'

createApi({
baseQuery: fetchBaseQuery({ baseUrl: '/' }),
endpoints: (build) => ({
listItems: build.query({
query: (pageNumber) => `/listItems?page=${pageNumber}`,

serializeQueryArgs: ({ endpointName }) => {
return endpointName
},

merge: (currentCache, newItems) => {
currentCache.push(...newItems)
},

forceRefetch({ currentArg, previousArg }) {
return currentArg !== previousArg
},
}),
}),
})
onQueryStarted

(optional)

Available to both queries and mutations.

A function that is called when you start each individual query or mutation. The function is called with a lifecycle api object containing properties such as queryFulfilled, allowing code to be run when a query is started, when it succeeds, and when it fails (i.e. throughout the lifecycle of an individual query/mutation call).

Can be used in mutations for optimistic updates.

Lifecycle API properties

Mutation onQueryStarted signature

async function onQueryStarted(
arg: QueryArg,
{
dispatch,
getState,
extra,
requestId,
queryFulfilled,
getCacheEntry,
}: MutationLifecycleApi,
): Promise<void>

Query onQueryStarted signature

async function onQueryStarted(
arg: QueryArg,
{
dispatch,
getState,
extra,
requestId,
queryFulfilled,
getCacheEntry,
updateCachedData,
}: QueryLifecycleApi,
): Promise<void>

onQueryStarted query lifecycle example

import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query'
import { messageCreated } from './notificationsSlice'

export interface Post {
id: number
name: string
}

const api = createApi({
baseQuery: fetchBaseQuery({
baseUrl: '/',
}),
endpoints: (build) => ({
getPost: build.query<Post, number>({
query: (id) => `post/${id}`,
async onQueryStarted(id, { dispatch, queryFulfilled }) {

dispatch(messageCreated('Fetching post...'))
try {
const { data } = await queryFulfilled

dispatch(messageCreated('Post received!'))
} catch (err) {

dispatch(messageCreated('Error fetching post!'))
}
},
}),
}),
})

onQueryStarted query lifecycle example

import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query'
import { messageCreated } from './notificationsSlice'

const api = createApi({
baseQuery: fetchBaseQuery({
baseUrl: '/',
}),
endpoints: (build) => ({
getPost: build.query({
query: (id) => `post/${id}`,
async onQueryStarted(id, { dispatch, queryFulfilled }) {

dispatch(messageCreated('Fetching post...'))
try {
const { data } = await queryFulfilled

dispatch(messageCreated('Post received!'))
} catch (err) {

dispatch(messageCreated('Error fetching post!'))
}
},
}),
}),
})
onCacheEntryAdded

(optional)

Available to both queries and mutations.

A function that is called when a new cache entry is added, i.e. when a new subscription for the endpoint + query parameters combination is created. The function is called with a lifecycle api object containing properties such as cacheDataLoaded & cacheDataRemoved, allowing code to be run when a cache entry is added, when cache data is loaded, and when the cache entry is removed (i.e. throughout the lifecycle of a cache entry).

Can be used for streaming updates.

Cache Lifecycle API properties

Mutation onCacheEntryAdded signature

async function onCacheEntryAdded(
arg: QueryArg,
{
dispatch,
getState,
extra,
requestId,
cacheEntryRemoved,
cacheDataLoaded,
getCacheEntry,
}: MutationCacheLifecycleApi,
): Promise<void>

Query onCacheEntryAdded signature

async function onCacheEntryAdded(
arg: QueryArg,
{
dispatch,
getState,
extra,
requestId,
cacheEntryRemoved,
cacheDataLoaded,
getCacheEntry,
updateCachedData,
}: QueryCacheLifecycleApi,
): Promise<void>
Schema Validation

Endpoints can have schemas for runtime validation of query args, responses, and errors. Any Standard Schema compliant library can be used.

When used with TypeScript, schemas can also be used to infer the type of that value instead of having to declare it.

warning

By default, schema failures are treated as fatal, meaning that normal error handling such as tag invalidation will not be executed.

In order for schema failures to be treated as non-fatal, you must provide a catchSchemaFailure function, to convert the schema failure into an error shape matching the base query errors.

catchSchemaFailure example

const api = createApi({
baseQuery: fetchBaseQuery({ baseUrl: '/' }),
catchSchemaFailure: (error, info) => ({
status: 'CUSTOM_ERROR',
error: error.schemaName + ' failed validation',
data: error,
}),
endpoints: (build) => ({

}),
})
argSchema

(optional)

A schema for the arguments to be passed to the query or queryFn.

import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react'
import * as v from "valibot"

const api = createApi({
baseQuery: fetchBaseQuery({ baseUrl: '/' }),
endpoints: (build) => ({
getPost: build.query<Post, { id: number }>({
query: ({ id }) => `/post/${id}`,
argSchema: v.object({ id: v.number() }),
}),
})
})
responseSchema

(optional)

A schema for the result (including transformResponse if provided).

import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react'
import * as v from "valibot"

const postSchema = v.object({ id: v.number(), name: v.string() })
type Post = v.InferOutput<typeof postSchema>

const api = createApi({
baseQuery: fetchBaseQuery({ baseUrl: '/' }),
endpoints: (build) => ({
getPost: build.query<Post, { id: number }>({
query: ({ id }) => `/post/${id}`,
responseSchema: postSchema,
}),
})
})
rawResponseSchema

(optional, not applicable with queryFn)

errorResponseSchema

(optional)

A schema for the error object returned by the query or queryFn (including transformErrorResponse if provided).

import { createApi } from '@reduxjs/toolkit/query/react'
import * as v from "valibot"
import { customBaseQuery, baseQueryErrorSchema } from "./customBaseQuery"

const api = createApi({
baseQuery: customBaseQuery,
endpoints: (build) => ({
getPost: build.query<Post, { id: number }>({
query: ({ id }) => `/post/${id}`,
errorResponseSchema: baseQueryErrorSchema,
}),
})
})
rawErrorResponseSchema

(optional, not applicable with queryFn)

metaSchema

(optional)

A schema for the meta property returned by the query or queryFn.

import { createApi } from '@reduxjs/toolkit/query/react'
import * as v from "valibot"
import { customBaseQuery, baseQueryMetaSchema } from "./customBaseQuery"

const api = createApi({
baseQuery: customBaseQuery,
endpoints: (build) => ({
getPost: build.query<Post, { id: number }>({
query: ({ id }) => `/post/${id}`,
metaSchema: baseQueryMetaSchema,
}),
})
})
Return value

See the "created Api" API reference


RetroSearch is an open source project built by @garambo | Open a GitHub Issue

Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo

HTML: 3.2 | Encoding: UTF-8 | Version: 0.7.4