Перейти к основному содержимому

Web и сеть

Для чего модуль

Научиться быстро разбирать сетевые проблемы и уверенно отвечать на вопросы по HTTP/API на собеседовании.

Результат после прохождения

  1. Вы объясняете путь запроса от браузера до сервера и обратно.
  2. Уверенно диагностируете проблемы CORS, кэша и latency.
  3. Проектируете API-взаимодействия с учетом надежности и ошибок.

Термины и аббревиатуры

ТерминКоротко
HTTPПротокол запрос-ответ
CORSОграничение чтения cross-origin
ETagВерсия ресурса
TTFBВремя до первого байта
IdempotencyПовтор без двойного эффекта

Фокус по грейдам

  1. Junior: понимать базовые механики и объяснять их простыми примерами.
  2. Middle: применять тему в продуктовых сценариях с учетом рисков и ограничений.
  3. Senior: управлять архитектурными trade-offs, метриками и эволюцией решения.

Как работать с модулем

  1. Берите один сетевой кейс на урок.
  2. Фиксируйте: симптом -> гипотеза -> проверка -> решение.
  3. После урока обновляйте чек-лист диагностики.

Программа модуля

Урок 1. HTTP и кэширование

Цель: уверенно читать и проектировать HTTP-взаимодействия без мифов.

1. HTTP-методы, безопасность и идемпотентность

Частая ошибка на собеседовании: путать safe и idempotent.

МетодSafeIdempotentТиповой смысл
GETДаДаПрочитать ресурс
HEADДаДаПрочитать только headers
PUTНетДаПолностью заменить ресурс
DELETEНетДаУдалить ресурс
POSTНетОбычно нетСоздать ресурс/запустить действие
PATCHНетОбычно нетЧастично изменить ресурс

Как это использовать в реальном API:

  1. Для безопасного чтения используйте GET и исключайте побочные эффекты.
  2. Для повторяемых операций (повтор запроса, retry) опирайтесь на идемпотентные методы или Idempotency-Key.
  3. Для ошибок разделяйте клиентские (4xx) и серверные (5xx) причины.

Быстрый ориентир по статусам:

  1. 200/204 - операция выполнена.
  2. 304 - можно использовать кэшированную версию.
  3. 400/422 - проблема во входных данных.
  4. 401/403 - проблема доступа (не путать между собой).
  5. 404 - ресурс не найден.
  6. 409 - конфликт состояния (например, версия ресурса).
  7. 429 - превышен лимит запросов.

2. Кэширование: Cache-Control, ETag, 304

Цель кэша: не делать лишние network round-trip и уменьшать latency.

Типовой flow с валидацией по ETag:

GET /api/profile HTTP/1.1
Host: app.example.com

HTTP/1.1 200 OK
Cache-Control: private, max-age=60
ETag: "profile-v42"
Content-Type: application/json

Через минуту клиент делает conditional request:

GET /api/profile HTTP/1.1
Host: app.example.com
If-None-Match: "profile-v42"

HTTP/1.1 304 Not Modified
Cache-Control: private, max-age=60
ETag: "profile-v42"

Что важно понимать:

  1. max-age задает "свежесть" ответа.
  2. ETag и If-None-Match дают проверку версии ресурса.
  3. 304 возвращает только метаданные, а тело берется из кэша клиента.
  4. Для персональных данных используйте private, для публичных ассетов - public.

Антипаттерны:

  1. Кэшировать ответы с user-specific данными как public.
  2. Отдавать агрессивный кэш на эндпоинт, который часто меняется, без стратегии инвалидации.
  3. Смешивать бизнес-ошибки и транспортные ошибки в один неструктурированный текст.

3. Единый контракт ошибок API

Минимальный контракт, который удобно логировать и разбирать:

{
"error": {
"code": "PROFILE_NOT_FOUND",
"message": "Profile does not exist",
"context": {
"profileId": "123"
},
"traceId": "0a12fcd9-7f5f-4a6f-bce2-3ec0b09dfaa8"
}
}

Зачем это нужно:

  1. FE может стабильно маппить code в UX-сценарий.
  2. traceId связывает frontend-лог и backend-трассировку.
  3. context снижает время диагностики инцидентов.

Мини-задача (обязательная)

Разберите в DevTools три запроса из вашего проекта и заполните таблицу:

EndpointМетодСтатусCache-Control / ETagМожно кэшировать?Почему

Требование: хотя бы один пример должен быть "кэшировать нельзя" с четким аргументом.

Разбор-ориентир (как проверять себя)

  1. GET /api/catalog с Cache-Control: public, max-age=120 обычно кэшируется.
  2. GET /api/me с персональными данными - только private, либо вообще без кэша в зависимости от требований актуальности.
  3. POST /api/orders не должен кэшироваться браузером как обычное чтение ресурса.

Для junior и для senior

Junior focus:

  1. Четко отличать safe и idempotent.
  2. Уметь объяснить разницу между 401 и 403.
  3. Понимать, зачем нужен ETag.

Senior focus:

  1. Проектировать стратегию кэширования по типам endpoint.
  2. Учитывать инвалидацию и риск stale-данных в UI.
  3. Стандартизировать error contract для всех сервисов команды.

Что спросит интервьюер: когда GET может быть небезопасным и почему PUT называют идемпотентным.

Критерий готовности по уроку: вы можете за 2-3 минуты разобрать любой HTTP-запрос из DevTools и предложить улучшения по кэшу и контракту ошибок.

Урок 2. DNS, TLS и latency

Цель: понимать, где теряется время до первого байта.

1. Из чего реально складывается задержка

Когда "endpoint медленный", важно разложить время, а не гадать.

Типовые этапы в DevTools Waterfall:

  1. DNS lookup - поиск IP по домену.
  2. Initial connection - TCP-соединение.
  3. SSL/TLS - согласование защищенного канала.
  4. TTFB - время до первого байта ответа.
  5. Content download - скачивание тела ответа.

Упрощенная модель: Latency ~= DNS + Connect + TLS + Server processing (часть TTFB) + Download

Практический вывод:

  1. Большой TTFB обычно указывает на backend/DB/очереди или удаленный регион.
  2. Большой Content download часто связан с тяжелым payload.
  3. Повторные запросы без роста DNS/TLS могут быть быстрее за счет keep-alive и кэша.

2. Почему локально быстро, а в проде медленно

Локальный стенд почти всегда "тепличный":

  1. Малая задержка до сервиса (один регион).
  2. Меньше сетевых hops и нет реального мобильного канала.
  3. Меньше конкуренции за ресурсы, чем в проде.

Что проверять первым:

  1. География пользователей и регион backend.
  2. Размер JSON/медиа, сжатие (gzip/br), pagination.
  3. Кэширование на CDN/edge.
  4. Холодные старты или деградация зависимостей на backend.

3. Как отличать сетевую проблему от серверной

Быстрый диагностический шаблон:

  1. Если DNS/Connect/TLS высокие на многих endpoint одновременно - ищите сеть/маршрут/инфраструктуру.
  2. Если узкое место только в TTFB одного-двух endpoint - вероятен backend-код или БД.
  3. Если высокий только Content download - оптимизируйте ответ (объем, формат, компрессия).

Проверочные вопросы к себе:

  1. Проблема глобальная или только для конкретной страницы/API?
  2. Воспроизводится ли в другом регионе/сети?
  3. Есть ли корреляция с ростом server-side метрик (p95/p99 latency)?

4. Мини-кейс (как объяснять на интервью)

Ситуация: экран каталога открывается 3.8s, пользователь жалуется на "тормоза".

Разбор:

  1. DNS + Connect + TLS = 120ms (нормально).
  2. TTFB = 2.9s (основная проблема).
  3. Download = 700ms при ответе 1.8MB (вторичная проблема).

Решение:

  1. На backend ввели пагинацию и убрали лишние поля.
  2. Добавили сжатие и короткий кэш для стабильно повторяемых данных.
  3. Вынесли тяжелые вычисления из sync-path запроса.

Результат: TTFB снизился до 900ms, payload до 420KB, итоговое время заметно сократилось.

Мини-задача (обязательная)

Возьмите один медленный endpoint и заполните таблицу:

EndpointDNSConnectTLSTTFBDownloadГлавный bottleneckЧто менять

Требование: обоснуйте одну гипотезу и один способ проверки гипотезы.

Для junior и для senior

Junior focus:

  1. Читать waterfall и находить самый дорогой этап.
  2. Понимать разницу между TTFB и Download.
  3. Давать простую гипотезу и проверку.

Senior focus:

  1. Приоритизировать улучшения по p95/p99, а не по единичному замеру.
  2. Связывать сетевые симптомы с backend и инфраструктурой.
  3. Проектировать mitigation-план: кэш, payload budget, деградация UX при медленной сети.

Что спросит интервьюер: как отличить проблему сети от медленного backend-кода.

Критерий готовности по уроку: вы можете по одному waterfall объяснить, где теряется время, и предложить 2 реалистичных улучшения с ожидаемым эффектом.

Урок 3. CORS и API-контракты

Цель: не путать CORS, авторизацию и контракт API.

1. Что CORS делает, а что не делает

CORS управляет тем, может ли браузерный frontend читать ответ другого origin. Это не механизм авторизации и не защита API "сама по себе".

Важно разделять:

  1. CORS - браузерное ограничение на чтение ответа.
  2. AuthN/AuthZ - проверка личности и прав доступа на сервере.
  3. CSRF/XSS - отдельные классы угроз, которые CORS не закрывает.

2. Same-origin policy и preflight

Когда браузер делает preflight (OPTIONS):

  1. Метод не "simple" (PUT, PATCH, DELETE и т.д.).
  2. Есть нестандартные headers (например, Authorization).
  3. Content-Type не входит в "simple" набор.

Типовой ответ сервера на preflight:

HTTP/1.1 204 No Content
Access-Control-Allow-Origin: https://app.example.com
Access-Control-Allow-Methods: GET,POST,PUT,PATCH,DELETE,OPTIONS
Access-Control-Allow-Headers: Content-Type, Authorization, X-Request-Id
Access-Control-Allow-Credentials: true
Vary: Origin

Критичные моменты:

  1. При Allow-Credentials: true нельзя использовать Allow-Origin: *.
  2. Всегда задавайте Vary: Origin, чтобы не сломать кэширование.
  3. Разрешайте только нужные методы и заголовки, а не "всё подряд".

3. Политика CORS по средам

Практичная схема:

  1. dev: whitelist локальных origin (http://localhost:3000, http://localhost:5173).
  2. stage: только домены стенда и QA-окружения.
  3. prod: только production-origin (без wildcard).

Антипаттерны:

  1. Единая permissive-политика для всех окружений.
  2. * в production "для скорости разработки".
  3. Отсутствие аудита разрешенных origin после релизов.

4. API-контракты и обратная совместимость

Базовые правила стабильного API:

  1. Предпочитайте additive changes: добавлять поля безопаснее, чем удалять/переименовывать.
  2. Для breaking changes фиксируйте версию (/v2 или versioned media type).
  3. Введите deprecation window с датой отключения и коммуникацией клиентам.

Минимальный lifecycle изменения:

  1. Объявили deprecated поле и срок удаления.
  2. Обновили клиентов и метрики использования старого поля.
  3. Удалили поле после окна миграции.

Мини-задача (обязательная)

Опишите для своего учебного API:

  1. CORS-политику для dev/stage/prod.
  2. Правила для breaking/non-breaking изменений.
  3. Шаблон уведомления о деприкации (что, когда, кого затрагивает).

Проверка качества: ваш документ должен позволять новому разработчику настроить CORS и выпустить изменение API без поломки клиентов.

Для junior и для senior

Junior focus:

  1. Уметь объяснить preflight и причину OPTIONS.
  2. Не путать CORS и авторизацию.
  3. Понимать, почему Access-Control-Allow-Origin: * часто опасен.

Senior focus:

  1. Проектировать environment-specific CORS policy без компромиссов по безопасности.
  2. Управлять эволюцией API через versioning/deprecation процесс.
  3. Связывать контрактные изменения с monitoring и rollout-стратегией.

Что спросит интервьюер: почему «включить * в CORS» обычно плохая идея.

Критерий готовности по уроку: вы можете предложить безопасную CORS-политику и план эволюции API-контракта без регрессий для существующих клиентов.

Урок 4. Наблюдаемость и диагностика

Цель: выстроить воспроизводимый процесс сетевой диагностики.

1. Что наблюдать в первую очередь

Базовый набор сигналов для frontend-диагностики:

  1. Network waterfall: где тратится время по этапам запроса.
  2. Status + payload: пришли ли данные нужной структуры.
  3. Server-Timing и traceId: есть ли связь с backend-метриками.
  4. UI-состояния: loading, empty, error, partial data.

Минимальная дисциплина:

  1. Любой инцидент разбирается на фактах из логов/метрик, а не на предположениях.
  2. Для каждого инцидента фиксируется timeline: что увидели, что проверили, что подтвердили.
  3. После фикса добавляется проверка, чтобы кейс не вернулся.

2. Retry, timeout, cancellation, circuit-breaker

Эти механизмы решают разные проблемы:

  1. timeout ограничивает ожидание одного запроса.
  2. retry полезен для временных сбоев (502/503/504, сетевой шум).
  3. cancellation (AbortController) защищает от устаревших ответов.
  4. circuit-breaker временно "закрывает" проблемный endpoint и снижает каскадные ошибки.

Практические правила:

  1. Не ретраить безусловно 4xx ошибки.
  2. Для retry используйте ограничение попыток и backoff.
  3. Всегда логируйте причину таймаута/отмены отдельно от бизнес-ошибок.

3. Корреляция FE и backend

Без корреляции вы видите только "симптом" на клиенте.

Что должно быть в контракте наблюдаемости:

  1. X-Request-Id или traceId в запросе и ответе.
  2. Единый формат frontend error log (route, endpoint, status, traceId, user action).
  3. Привязка к релизу (build/version), чтобы быстро находить регрессии.

Пример полезной frontend-записи:

{
"route": "/catalog",
"endpoint": "/api/catalog?filter=sale",
"status": 200,
"traceId": "4f6e43a7-b9f5-4c15-8e32-9f1d8106fba1",
"payloadItems": 0,
"uiState": "empty_unexpected",
"build": "web-2026.02.11-3"
}

4. Runbook для кейса: 200 OK, но UI пустой

Пошаговый шаблон:

  1. Проверить network: endpoint, query params, status, размер тела.
  2. Сравнить фактический payload с ожидаемой схемой UI.
  3. Проверить клиентскую фильтрацию/маппинг: не "съедает" ли данные трансформация.
  4. Проверить feature flags и условия рендера (роль, регион, эксперимент).
  5. Найти traceId и сверить backend-логи по тому же запросу.
  6. Зафиксировать root cause и добавить защиту (валидация схемы, fallback, alert).

Типовые причины:

  1. Контракт API изменился, а клиент ожидает старое поле.
  2. Неправильные query params после изменения роутинга.
  3. Ошибка маппинга на клиенте при корректном ответе сервера.

Мини-задача (обязательная)

Соберите runbook для вашего кейса "200 OK, но пустой экран" и добавьте:

  1. Чек-лист проверки (минимум 8 шагов).
  2. Какие логи/метрики нужны на FE и BE.
  3. Какой alert должен сработать, если проблема повторится.

Критерий качества: другой разработчик должен по вашему runbook локализовать проблему без вашей помощи.

Для junior и для senior

Junior focus:

  1. Уметь читать network + response body вместе, а не по отдельности.
  2. Отличать пустые данные "по бизнесу" от пустых данных "из-за бага".
  3. Работать по готовому runbook без пропуска шагов.

Senior focus:

  1. Строить end-to-end observability между FE, API gateway и сервисами.
  2. Вводить SLO/alerting для критичных пользовательских сценариев.
  3. Уменьшать MTTR через стандарты логирования и postmortem-процесс.

Что спросит интервьюер: как вы действуете, если баг плавающий и не воспроизводится локально.

Критерий готовности по уроку: вы можете провести диагностику "200 OK, но UI пустой" до root cause и предложить превентивные меры, которые реально снижают повторяемость инцидента.

Практика

  1. Разберите 3 запроса в DevTools Network и определите bottleneck.
  2. Напишите runbook для кейса 200 OK, но пустой экран.
  3. Подготовьте шаблон API error contract (поля, коды, trace id).
  4. Закрепите в Junior JavaScript и Senior Frontend.
  5. Реализуйте диагностический сценарий в Песочнице.

Связь с треками и вопросами

  1. Треки: Junior трек, Middle трек, Senior трек.
  2. Вопросы: Junior JavaScript, Senior Frontend.
  3. Повторение: 3-5 вопросов без подсказок -> сверка с модулем -> повтор через 24 часа.

Критерий готовности

Вы даете структурный ответ: проблема -> гипотеза -> проверка -> решение -> метрика улучшения.

Артефакты после модуля

  1. Личный чек-лист сетевой диагностики.
  2. Документ по CORS/API-контрактам для учебного проекта.
  3. 2-3 истории из практики для собеседования (контекст -> действие -> результат).

Куда дальше

  1. Безопасность и хранение
  2. Рендеринг веб-страницы
  3. Web и сеть