Endpoints являются центральной частью конфигурации
createApi и представляют собой декларативное описание всех
операций взаимодействия с сервером. Каждый endpoint описывает конкретный
запрос или мутацию, а также правила кэширования, инвалидации и
формирования ключей кэша.
Endpoints не являются абстрактными «маршрутами API» в классическом смысле. Это функциональные описания поведения данных внутри клиентского состояния Redux Toolkit Query: как получать данные, когда считать их актуальными, как обновлять кэш и какие зависимости у этих данных.
Endpoints определяются внутри вызова createApi через
поле endpoints, которое представляет собой функцию с
параметром builder.
import { createApi, fetchBaseQuery } fr om '@reduxjs/toolkit/query/react';
export const api = createApi({
reducerPath: 'api',
baseQuery: fetchBaseQuery({ baseUrl: '/api' }),
endpoints: (builder) => ({
// endpoints здесь
})
});
builder предоставляет два основных метода:
builder.query — для получения данных (GET-подобные
операции)builder.mutation — для изменения данных (POST, PUT,
DELETE и т.п.)Query endpoint описывает операцию чтения данных. Он всегда должен быть детерминированным: одинаковые входные параметры → одинаковый результат кэширования.
getUsers: builder.query({
query: () => '/users'
})
Query endpoint принимает объект конфигурации:
query — функция, возвращающая строку или объект
запросаtransformResponse — преобразование ответаprovidesTags — теги для кэш-инвалидацииkeepUnusedDataFor — время хранения данных в кэшеserializeQueryArgs — управление ключом кэшаПример с параметрами:
getUserById: builder.query({
query: (id) => `/users/${id}`
})
Mutation endpoint описывает операции изменения состояния на сервере. В отличие от query, мутации не кэшируются как источник истины, но могут влиять на кэш query через теги.
addUser: builder.mutation({
query: (newUser) => ({
url: '/users',
method: 'POST',
body: newUser
})
})
invalidatesTagsКаждый endpoint можно представить как объект следующей логики:
Пример:
endpoints: (builder) => ({
getPosts: builder.query({
query: () => '/posts'
}),
createPost: builder.mutation({
query: (post) => ({
url: '/posts',
method: 'POST',
body: post
})
})
})
Каждый endpoint автоматически преобразуется в React hook (при
использовании @reduxjs/toolkit/query/react).
Правило именования:
useXxxQueryuseXxxMutationПример:
const { data } = useGetPostsQuery();
const [createPost] = useCreatePostMutation();
Endpoint становится связующим звеном между декларацией API и React-слоем.
RTK Query использует комбинацию имени endpoint и аргументов запроса для генерации cache key.
getUser: builder.query({
query: (id) => `/user/${id}`
})
Внутренне это преобразуется в:
getUser(1)
getUser(2)
Каждый вызов формирует отдельную запись в кэше.
Аргументы endpoint — это входные данные, которые передаются в
query функцию.
getProducts: builder.query({
query: ({ category, lim it }) =>
`/products?category=${category}&limit=${limit}`
})
Использование:
useGetProductsQuery({ category: 'books', limit: 10 });
Аргументы могут быть:
Важно: структура аргумента напрямую влияет на кэширование.
Используется для:
Характеристики:
Используется для:
Характеристики:
Endpoints могут быть связаны через систему тегов.
getPosts: builder.query({
query: () => '/posts',
providesTags: ['Posts']
}),
addPost: builder.mutation({
query: (post) => ({
url: '/posts',
method: 'POST',
body: post
}),
invalidatesTags: ['Posts']
})
Механизм:
Endpoints могут принимать параметры не только на уровне запроса, но и на уровне конфигурации.
Пример динамической логики:
getResource: builder.query({
query: ({ type, id }) => `/${type}/${id}`
})
Такой подход позволяет использовать один endpoint для нескольких сущностей, но требует аккуратного управления кэшем.
Определяет время хранения данных после удаления подписчиков.
getUsers: builder.query({
query: () => '/users',
keepUnusedDataFor: 60
})
Позволяет нормализовать ответ сервера.
getUsers: builder.query({
query: () => '/users',
transformResponse: (response) => response.data
})
Endpoints могут быть отключены условно через
skipToken:
useGetUserQuery(userId ?? skipToken);
Это предотвращает запуск запроса при отсутствии аргумента.
Endpoints в RTK Query не являются изолированными функциями. Они формируют:
Каждый endpoint становится узлом в графе зависимостей данных, где:
Если endpoint вызывается с теми же аргументами:
Если аргументы изменились:
getUsers: builder.query({
query: (params) => ({
url: '/users',
params
})
})
search: builder.query({
query: ({ q, page, sort }) => ({
url: '/search',
params: { q, page, sort }
})
})
updateUser: builder.mutation({
query: ({ id, ...patch }) => ({
url: `/users/${id}`,
method: 'PATCH',
body: patch
}),
invalidatesTags: (result, error, arg) => [
{ type: 'User', id: arg.id }
]
})
Endpoint проходит несколько стадий:
Каждый endpoint определяет не только URL запроса, но и участие в жизненном цикле данных внутри store.