HTTP: запрос и ответ

HTTP задаёт семантику обмена между клиентом и origin server. Запрос содержит method, target, headers и необязательное содержимое; ответ — status, headers и необязательное содержимое. Корректный API делает эту семантику наблюдаемой для клиента, прокси, кэша и оператора.

Зачем это на интервью

Тема показывает, умеет ли инженер проектировать контракт, который переживает timeout, retry и кэширование. Важнее не вспомнить все коды, а объяснить, почему конкретный код и заголовок позволяют клиенту принять безопасное решение.

Минимум для E4

  • Различать request target, method, header, representation и status code.
  • Объяснять safe (GET, HEAD, OPTIONS) и idempotent (PUT, DELETE) семантику.
  • Выбирать 2xx/4xx/5xx по ответственности за ошибку и не скрывать её в теле 200.
  • Знать назначение Content-Type, Accept, Authorization, Location, ETag, Cache-Control и Vary.

Content-Type описывает отправленное представление, а Accept — допустимые представления ответа. Сервер согласует content negotiation и может вернуть 406, если не может выбрать приемлемый вариант; origin также вправе проигнорировать Accept и отправить иной ответ. Заголовки Connection, Keep-Alive, Transfer-Encoding — hop-by-hop: прокси не переносит их как end-to-end контракт.

Углубление для E5/Senior

Повтор возникает не только при явном retry: балансировщик, SDK или пользователь могут не получить ответ после того, как сервер записал данные. Для mutating операции фиксируют idempotency key, область его уникальности, срок хранения результата и поведение при конфликтующем payload. Дедупликация после бизнес-коммита должна быть атомарной с наблюдаемым результатом.

Кэш валидирует представление через ETag и условный If-None-Match; ответ 304 не содержит нового тела. Cache-Control: max-age задаёт свежесть, no-store запрещает хранение, а no-cache требует revalidation — это не одно и то же. Vary обязан перечислять request headers, по которым различается ответ, иначе кэш может отдать чужую локаль или encoding.

Ключевые понятия

  • Representation — конкретная форма ресурса: JSON, HTML или изображение; ресурс и его representation не тождественны.
  • Safe method не должен менять наблюдаемое состояние; idempotent method имеет одинаковый предполагаемый эффект над состоянием сервера при одном или нескольких одинаковых запросах. Ответы и сопутствующие эффекты могут отличаться.
  • Conditional request делает обновление или чтение зависимым от validator (ETag, date), предотвращая lost update.
  • Problem details — структурированное описание ошибки с устойчивым machine-readable code, а не парсингом текста.

Типовые вопросы

  1. PUT всегда безопасно повторять?
    • PUT идемпотентен по предполагаемому эффекту над состоянием, но это не гарантирует exactly-once execution, одинаковый ответ или отсутствие сопутствующих действий. Handler должен обеспечить семантику изменения состояния, а email и журналирование могут потребовать отдельной дедупликации.
  2. 204 или 200 после удаления?
    • 204 удобен для успешного удаления без representation; 200 допустим, если возвращается полезное тело. Важна стабильность контракта.
  3. Зачем ETag при обновлении?
    • If-Match превращает запись в compare-and-swap: при устаревшей версии сервер отвечает 412, а не молча перезаписывает чужое изменение.
  4. Чем 401 отличается от 403?
    • 401 означает отсутствие или неприемлемость аутентификационных данных и может сопровождаться challenge; 403 — понятому сервером субъекту доступ запрещён.
  5. Почему нельзя ретраить любой 5xx?
    • Операция могла примениться, а ошибка возникнуть после неё; retry разрешён только при известной семантике, дедупликации и ограниченном backoff.
  6. Что означает no-cache?
    • Кэш может хранить ответ, но должен проверить его у origin перед повторным использованием; полный запрет хранения — no-store.

Практика

  • Реализуйте GET /orders/{id} с ETag и If-None-Match; критерий: повторный запрос получает 304, а изменение representation меняет validator.
  • Реализуйте POST /payments с idempotency key; критерий: два одинаковых запроса после потерянного ответа возвращают один payment ID, разные payload с тем же ключом отклоняются.
  • Опишите таблицу ошибок handler; критерий: для validation, authentication, forbidden, conflict и internal error есть status, stable code и тест.

Частые ошибки и ловушки

  • Путать no-cache с no-store и не задавать Vary для content negotiation.
  • Принимать Content-Type клиента на веру без лимита тела и валидации схемы.
  • Делать retry без deadline, jitter, лимита попыток и классификации ошибок.
  • Возвращать внутренний текст исключения вместо безопасного публичного сообщения и correlation ID.

Связанные темы

HTTP и Web · HTTP/1.1: соединения · REST и дизайн API · Совместимость API · Безопасность

Источники

  • RFC 9110, HTTP Semantics, разделы о methods, status codes и conditional requests.
  • RFC 9111, HTTP Caching.
  • RFC 9457, Problem Details for HTTP APIs.
  • MDN Web Docs: HTTP headers и HTTP caching.