Как проходит путь запроса от фронтенда до бэкенда и обратно
Что проверяют
Видите ли вы всю цепочку целиком, а не только свой код во view. Это разминка перед уточнениями: где здесь nginx, чем WSGI отличается от ASGI, почему браузер ругается на CORS и где в цепочке теряется время.
Как отвечать
Идите по шагам от клика до перерисовки страницы:
- браузер: код вызывает
fetchс методом, заголовками и телом, обычно JSON. Домен резолвится через DNS, поднимается TCP и TLS 1.3, запрос идёт по HTTP/2 или HTTP/3. Если кросс-доменный запрос не считается «простым» (например, сContent-Type: application/jsonили заголовкомAuthorization), браузер сначала шлёт preflightOPTIONS; - reverse proxy: nginx или облачный балансировщик завершает TLS, отдаёт статику, проксирует запрос на приложение, добавляет
X-Forwarded-For; - сервер приложения: gunicorn с воркерами для WSGI (Django, Flask) или uvicorn для ASGI (FastAPI, асинхронный Django). Он превращает HTTP-запрос в вызов Python-функции;
- фреймворк: цепочка middleware (сессии, аутентификация, CSRF), роутинг по URL, валидация входа (сериализаторы DRF, Pydantic в FastAPI), бизнес-логика;
- данные: ORM строит SQL, берёт соединение из пула, ходит в PostgreSQL, иногда в Redis за кешем;
- обратный путь: сериализация в JSON, код ответа, заголовки кеширования и CORS, снова middleware, nginx, браузер. На фронте разбираются статус и тело, обновляется состояние и интерфейс.
Хорошо добавить, где искать задержку: DNS и TLS-рукопожатие, очередь к воркерам gunicorn, запросы N+1 в ORM, сериализация больших ответов.
Где спотыкаются
Считают, что CORS защищает сервер. Это правило браузера: curl или другой бэкенд получит ответ без всяких заголовков, поэтому авторизацию CORS не заменяет.
Путают роли nginx и gunicorn. Nginx не исполняет Python, а gunicorn без прокси напрямую в интернет не выставляют.
Пропускают обработку ошибок: что вернёт API при невалидных данных (400 или 422), при отсутствии прав (401 против 403) и как фронтенд покажет это пользователю.