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

Конвертеры данных (DTO -> Model)

Руководство по разделению контрактов API и внутренним моделям данных приложения с помощью маппингов (DTO -> Domain Model).

Архитектура маппинга данных

Преимущества: Конвертеры изолируют UI от изменений на бэкенде, позволяют форматировать данные (даты, перечисления) и гарантируют типобезопасность на уровне слоев.

Структура файлов конвертеров сущности

Соглашения о наименовании

  • Конвертеры:

    Располагаются в папке converters. Файлы называются по шаблону [entity-name].converters.ts. Используют типы из соседней папки для трансформации данных.

  • Типы и Интерфейсы:

    Располагаются в папке types. Обязательно разделение на *.backend.interface.ts (сырые DTO) и *.interface.ts (модели для UI). Все типы экспортируются через index.ts.

01Маппинг в Frontend (Domain Model)

Преобразование сырых данных бэкенда (snake_case, строки вместо дат) в camelCase и типизированные объекты для UI. mapToFrontend — самый важный этап.

converters/booking-order.converters.ts
1import { formatDate } from "@/shared/lib/utils"; 2import { type IEntityBackend, type IEntity } from "../types"; 3 4export const mapEntityToFrontend = ( 5 data: IEntityBackend 6): IEntity => ({ 7 id: data.id, 8 fullName: data.full_name, 9 dateCreated: formatDate(data.created_at), 10 status: data.status_code 11});

02Маппинг в Backend (DTO)

Подготовка данных перед отправкой. Используется при создании или обновлении сущностей для возврата к формату DTO, ожидаемому API.

converters/booking-order.converters.ts
1import { 2 type IEntityBackend, 3 type IEntity 4} from "../types"; 5 6export const mapEntityToBackend = ( 7 data: Partial<IEntity> 8): Partial<IEntityBackend> => ({ 9 id: data.id, 10 full_name: data.fullName, 11 created_at: data.dateCreated, 12 status_code: data.status 13});

03Конвертация фильтров

Особый случай маппинга стейта поисковых фильтров в query-параметры. Позволяет удобно объединять массивы, обрабатывать пустые значения и специфичные форматы API.

converters/booking-order.converters.ts
1import { type IEntityFilters } from "../types"; 2 3export const mapEntityFiltersToBackend = ( 4 filters: IEntityFilters 5) => ({ 6 page: filters.page, 7 limit: filters.limit, 8 search: filters.search || undefined, 9 status: filters.status.length > 0 10 ? filters.status.join(",") 11 : undefined 12});

04Интеграция с RTK Query

Конвертеры внедряются прямо в описание эндпоинтов: transformResponse для получения данных и query (params/body) для отправки.

api/[entity-name].service.ts
1import { authApi } from "@/entities/auth/api/auth.api"; 2import { 3 mapEntityFiltersToBackend, 4 mapEntityPaginatedToFrontend, 5 mapEntityToBackend 6} from "../converters"; 7 8export const entityApi = authApi.injectEndpoints({ 9 endpoints: (builder) => ({ 10 getEntities: builder.query<TResponse, TFilters>({ 11 query: (filters) => ({ 12 url: "/entity/list", 13 params: mapEntityFiltersToBackend(filters) 14 }), 15 transformResponse: (response: TResponseBackend) => 16 mapEntityPaginatedToFrontend(response) 17 }), 18 updateEntity: builder.mutation<void, TEntity>({ 19 query: (body) => ({ 20 url: "/entity/update", 21 method: "POST", 22 body: mapEntityToBackend(body) 23 }) 24 }) 25 }) 26});