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

Mock Server (MSW)

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

Мокирование API (Документация MSW)

Преимущества: Позволяет тестировать сценарии ошибок, задержки сети и различные состояния данных без реального бэкенда.

Структура Mock-слоя

Правила именования и расположения

  • Хендлеры (Handlers):
    Располагаются в src/entities/[entity-name]/handlers/. Файлы называются [entity-name].handlers.ts. Содержат логику перехвата специфичных для сущности запросов.
  • Моки (Mocks):
    Располагаются в src/entities/[entity-name]/mock/. Файлы называются [entity-name].mock.ts. Содержат статические или динамические данные, имитирующие ответ сервера.
  • Конфигурация:
    Общие настройки MSW находятся в src/shared/api/msw/. Регистрация всех хендлеров происходит в handlers.ts.

011. Создание моков

Определяем массив данных, которые будет возвращать сервер. Используем интерфейсы из папки types/ для обеспечения типизации.
entities/[entity-name]/mock/[entity-name].mock.ts
1import { type IEntity } from "../types"; 2 3export const ENTITY_MOCK: IEntity[] = [ 4 { 5 id: "1", 6 fullName: "John Doe", 7 date: "2024-03-22", 8 status: "active" 9 }, 10 { 11 id: "2", 12 fullName: "Jane Smith", 13 date: "2024-03-21", 14 status: "pending" 15 } 16];

022. Описание хендлеров

Используем библиотеку msw для перехвата конкретных URL. Здесь же можно имитировать задержку сети или ошибки сервера.
entities/[entity-name]/handlers/[entity-name].handlers.ts
1import { HttpResponse, http } from "msw"; 2import { ENV } from "@/shared/config"; 3import { ENTITY_MOCK } from "../mock"; 4 5export const entityHandlers = [ 6 http.get(`${ENV.VITE_API_URL}/entity/list`, () => { 7 return HttpResponse.json({ 8 data: ENTITY_MOCK 9 }); 10 }), 11 12 http.post(`${ENV.VITE_API_URL}/entity/update`, async ({ request }) => { 13 const body = await request.json(); 14 return HttpResponse.json({ success: true, data: body }); 15 }) 16];

033. Конфигурация воркера

Создаем экземпляр worker-а в shared/api/msw/browser.ts для перехвата запросов в браузере.
shared/api/msw/browser.ts
1import { setupWorker } from "msw/browser"; 2import { handlers } from "./handlers"; 3 4export const worker = setupWorker(...handlers);

044. Реестр хендлеров

Собираем хендлеры всех сущностей в единый массив в shared/api/msw/handlers.ts.
shared/api/msw/handlers.ts
1import { entityOneHandlers } from "@/entities/entity-one/handlers"; 2import { entityTwoHandlers } from "@/entities/entity-two/handlers"; 3 4export const handlers = [ 5 ...entityOneHandlers, 6 ...entityTwoHandlers 7];

055. Инициализация в App

Создаем асинхронную функцию запуска в app/init/msw.ts, которая проверяет флаги окружения.
app/init/msw.ts
1import { ENV } from "@/shared/config"; 2 3export const initMsw = async () => { 4 if (import.meta.env.DEV || ENV.VITE_ENABLE_MSW === "true") { 5 const { worker } = await import("@/shared/api/msw/browser"); 6 return worker.start({ 7 onUnhandledRequest: "bypass" 8 }); 9 } 10 return Promise.resolve(); 11};

066. Точка входа (Main)

Дожидаемся запуска MSW перед рендерингом приложения в src/main.tsx.
main.tsx
1import { StrictMode } from "react"; 2import { createRoot } from "react-dom/client"; 3import { initMsw } from "./app/init/msw"; 4import App from "./app"; 5 6const container = document.getElementById("root"); 7 8if (container) { 9 const root = createRoot(container); 10 11 initMsw().then(() => { 12 root.render( 13 <StrictMode> 14 <App /> 15 </StrictMode> 16 ); 17 }); 18}

077. Переменные окружения

Управление включением моков через файл .env.
.env
1VITE_ENABLE_MSW=true