Mock-сервер
Cloudflare Worker находится между браузером и реальным API, обеспечивая прозрачное проксирование с поддержкой CORS и анонимизированными mock-данными.
Адрес воркера: https://ittop-mock.blazer19092008.workers.dev/api/v2
Реальный API: https://msapi.top-academy.ru/api/v2
Зачем это нужно
Swagger UI на github.io не может вызывать реальный API напрямую:
- CORS — API не возвращает
Access-Control-Allow-Origin, поэтому браузер блокирует кросс-доменные ответы - Origin/Referer — API требует эти заголовки равными
journal.top-academy.ru, что браузер на github.io сделать не может
Воркер решает обе проблемы: добавляет CORS-заголовки к каждому ответу и подставляет Origin/Referer при проксировании на реальный API.
Логика маршрутизации
Воркер обрабатывает каждый запрос по следующей логике:
Запрос поступает
│
├─ OPTIONS (CORS preflight)?
│ └─ → 204 No Content + CORS-заголовки
│
├─ POST /auth/login?
│ ├─ Проксирование на реальный API
│ │ ├─ 2xx → возврат реального ответа + CORS-заголовки
│ │ └─ 4xx / ошибка сети → возврат mock-данных
│ └─ Нет mock-данных → 404 Not Found
│
├─ Есть заголовок Authorization: Bearer ...?
│ └─ Проксирование на реальный API + CORS-заголовки
│ (Origin/Referer/User-Agent подставляются автоматически)
│
└─ Нет токена?
├─ Mock-данные есть для этого пути → возврат mock + CORS-заголовки
└─ Нет mock-данных → 404 Not Found
Mock-данные
При отсутствии Bearer-токена воркер возвращает анонимизированные mock-данные из встроенного объекта MOCK. Данные поступают из пайплайна проекта:
- Сбор — реальные ответы API запрашиваются с учётными данными студента
- Анонимизация — чувствительные данные (имена, ID, даты) заменяются сгенерированными значениями через Faker
- Встраивание —
mock/build_worker.pyвнедряет анонимизированные данные вworker.jsкак константуMOCK - Деплой —
wrangler deployотправляет воркер в Cloudflare
Mock-данные покрывают все 34 эндпоинта — каждый путь, который собирает проект. Структура mock-ответов идентична реальным ответам API (те же имена полей и типы), только значения анонимизированы.
Как выглядят mock-данные
Пример mock-ответа для POST /auth/login:
{
"access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...",
"refresh_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...",
"expires_in_access": 7200,
"expires_in_refresh": 86400,
"user_type": 0,
"city_data": { "id": 1, "name": "Generated City" },
"user_role": "student"
}
access_token в mock — реальная структура JWT, но с невалидными подписями. Его нельзя использовать для аутентификации на реальном API.
Когда mock-данные могут быть устаревшими
Если API был недоступен во время ночного сбора, пайплайн добавляет предупреждение в openapi.json, а mock-данные отражают последний успешный сбор. Шаг CI validate проверяет соответствие схем — если структура API изменилась, пайплайн падает и открывает Issue в GitHub.
Обновление mock-данных
Mock-данные обновляются автоматически пайплайном CI:
tests → collect → validate → anonymize → publish
↘ build_worker → deploy
Ручное обновление:
# Полный пайплайн (требует JOURNAL_LOGIN и JOURNAL_PASSWORD)
JOURNAL_LOGIN=ваш_логин JOURNAL_PASSWORD=ваш_пароль uv run main.py
# Только пересборка воркера из существующих анонимизированных данных
uv run main.py --step publish
python mock/build_worker.py
wrangler deploy
Ограничения
| Ограничение | Подробности |
|---|---|
| HTTP-методы | Поддерживаются только GET и POST — PATCH, PUT, DELETE не проксируются и не мокаются |
| Операции записи | Нет mock-поддержки для отправки ДЗ, обновления профиля и т.д. — собираются только читающие эндпоинты |
| Свежесть данных | Mock-данные отражают последний успешный сбор; могут быть устаревшими до 24 часов |
| Лимиты Cloudflare | Воркер имеет лимит CPU 50 мс (бесплатный план) и лимит памяти 128 МБ |
| Логин mock | Mock-токен /auth/login нельзя использовать на реальном API — он только для изучения структуры |
Сборка и деплой
mock/build_worker.py— генерируетworker.jsиз шаблона + анонимизированных данных изdata/examples/latest.jsonmock/wrangler.toml— конфигурация Cloudflare Wrangler (ittop-mock,compatibility_date: 2025-01-01)- Деплой:
wrangler deploy(автоматически через CI, шагworker)