Platform
    • RTK Query
    • Mock Server (MSW)
    • Data Converters
Projects
  • API Connections & Tools
  1. Documentation
  2. Documentation

Data Management via RTK Query

Detailed guide on RTK Query architecture (Code Splitting).

RTK Query Code Splitting Architecture

Architectural Invariant: It is forbidden to use createApi inside business modules of entities. The project uses a single caching core, divided into configuration and authorization layers. Features and entities "inject" their endpoints into the authorized core.

API Core File Structure

01Global Tag Registry (Shared Layer)

For correct operation of invalidation providesTags / invalidatesTags, all possible tags are collected in a centralized config.

shared/api/backend/tags.config.ts
1export const ENUM_API_TAGS = { 2 USER: "User", 3 BOOKING_ORDERS: "Booking Orders", 4 // и другие теги... 5} as const;

02Base API Instance (Shared Layer)

The lowest level of network requests. No interceptors, only pure fetchBaseQuery and global tag registration.

shared/api/backend/base.api.ts
1import { createApi, fetchBaseQuery } from "@reduxjs/toolkit/query/react"; 2import { ENV } from "@/shared/config"; 3import { ENUM_API_TAGS } from "./tags.config"; 4 5export const baseApi = createApi({ 6 baseQuery: fetchBaseQuery({ 7 baseUrl: ENV.VITE_API_URL, 8 credentials: "include" 9 }), 10 reducerPath: "baseApi", 11 endpoints: () => ({}), 12 tagTypes: Object.values(ENUM_API_TAGS) 13});

03Authorization Interceptor (Entities Layer)

A wrapper (Middleware) over the base request. It allows centralized handling of session loss (e.g., error 401) and executing logout() for the entire application.

entities/auth/api/auth-base-query.ts
1import { type BaseQueryFn, type FetchArgs, type FetchBaseQueryError, fetchBaseQuery } from "@reduxjs/toolkit/query/react"; 2import { ENV } from "@/shared/config"; 3import { logout } from "@/entities/user/slice/user.slice"; 4 5export const authBaseQuery: BaseQueryFn<string | FetchArgs, unknown, FetchBaseQueryError> = async (args, api, extraOptions) => { 6 const baseQuery = fetchBaseQuery({ baseUrl: ENV.VITE_API_URL, credentials: "include" }); 7 const result = await baseQuery(args, api, extraOptions); 8 9 if (result.error && result.error.status === 401) { 10 api.dispatch(logout()); 11 } 12 return result; 13};

04Authorized API Instance (Entities Layer)

Initialization of a protected API instance (usually exported from the auth entity) using a custom authBaseQuery.

entities/auth/api/auth.api.ts
1import { createApi } from "@reduxjs/toolkit/query/react"; 2import { ENUM_API_TAGS } from "@/shared/api/backend/tags.config"; 3import { authBaseQuery } from "./auth-base-query"; 4 5export const authApi = createApi({ 6 baseQuery: authBaseQuery, 7 reducerPath: "authApi", 8 endpoints: () => ({}), 9 tagTypes: Object.values(ENUM_API_TAGS) 10});

05Endpoint Injection (Entities Layer)

The final stage in the target entity. We import authApi and call injectEndpoints. This code becomes the public service of the entity.

entities/booking/order/api/booking-order.service.ts
1import { authApi } from "@/entities/auth/api/auth.api"; 2 3export const bookingOrderApi = authApi.injectEndpoints({ 4 endpoints: (builder) => ({ 5 getBookingOrders: builder.query<TResponse, TFilters>({ 6 query: (filters) => ({ url: "/booking/orders" }), 7 providesTags: [ENUM_API_TAGS.BOOKING_ORDERS] 8 }) 9 }) 10});