Логотип Workflow

Article

Http Response Statuses

Stage 4. Response Status Codes

HTTP-статус — это первый и самый короткий ответ сервера о результате операции. Клиентские библиотеки, ретраи, мониторинг и алерты в первую очередь ориентируются именно на код ответа. Поэтому корректные статусы — не “косметика API”, а часть эксплуатационной надежности.

Status codes map

Полезно воспринимать коды как систему из трёх больших групп. 2xx означает успешную обработку. 4xx означает, что проблема в запросе, правах или контексте клиента. 5xx означает сбой на стороне сервера. Если команда стабильно придерживается этой классификации, диагностика инцидентов ускоряется уже на уровне логов и дашбордов.

На практике особенно важны несколько кодов. 200 OK подходит для успешного чтения или обновления с телом ответа. 201 Created показывает, что появился новый ресурс. 204 No Content полезен, когда операция успешна, но тело не требуется. Для ошибок клиента чаще всего нужны 400, 401, 403, 404, 409, 422. Для внутренних сбоев — 500.

Проблема “всегда возвращаем 200” кажется удобной только в начале. Потом это ломает протокольную семантику: клиент вынужден читать кастомные поля в теле, мониторинг перестаёт отличать успех от ошибки, а автоматические ретраи начинают работать неправильно. В результате растёт сложность клиента и ухудшается предсказуемость всей системы.

Статус должен согласовываться с телом ошибки. Если сервер возвращает 409 Conflict, тело должно объяснять конфликт состояния, а не писать абстрактное “something went wrong”. Эта связка особенно важна при интеграциях: партнёрские команды часто автоматизируют реакцию именно по паре “код + тип ошибки”.

{
  "error": "conflict",
  "message": "order already confirmed",
  "traceId": "a733ed51"
}

Отдельно нужно различать 401 и 403. 401 означает, что клиент не аутентифицирован или токен невалиден. 403 означает, что аутентификация есть, но прав недостаточно. Когда эти коды путают, клиенты неправильно строят UX: вместо запроса логина показывают “доступ запрещён” и наоборот.

Код 422 Unprocessable Entity полезен там, где JSON синтаксически корректен, но бизнес-правила не выполняются. Это позволяет отделить “плохой формат” (400) от “понятный запрос, но недопустимое действие” (422). Для сложных форм и валидации это различие повышает качество обратной связи пользователю.

Важно, чтобы одинаковые сценарии в разных endpoint-ах возвращали одинаковые статусы. Если один и тот же тип ошибки в одном месте даёт 409, а в другом 400, клиенту приходится писать лишние ветки обработки, а QA теряет целостную матрицу ожиданий.

Справочная таблица HTTP-статусов

КлассКодНазваниеПрактический смысл
1xx100ContinueСервер получил заголовки запроса, клиент может отправлять тело.
1xx101Switching ProtocolsСервер согласился переключиться на другой протокол.
1xx103Early HintsПредварительный ответ, чтобы клиент начал preload ресурсов.
2xx200OKСтандартный успешный ответ.
2xx201CreatedЗапрос успешен, создан новый ресурс.
2xx202AcceptedЗапрос принят в обработку, но ещё не завершён.
2xx203Non-Authoritative InformationУспех, но часть данных может быть из промежуточного/внешнего источника.
2xx204No ContentУспешно, но без тела ответа.
2xx205Reset ContentУспешно, без тела; клиенту нужно сбросить форму/представление.
2xx206Partial ContentВозвращена только часть ресурса (range-запрос).
3xx300Multiple ChoicesДоступно несколько вариантов ресурса/перехода.
3xx301Moved PermanentlyРесурс навсегда переехал на новый URL.
3xx302FoundРесурс временно находится по другому URL.
3xx303See OtherРезультат нужно запрашивать по другому URL (часто после POST).
3xx304Not ModifiedРесурс не изменился, можно использовать кэш.
3xx307Temporary RedirectВременный редирект с сохранением исходного HTTP-метода.
3xx308Permanent RedirectПостоянный редирект с сохранением исходного HTTP-метода.
4xx400Bad RequestСервер не может обработать запрос из-за некорректного синтаксиса/формы.
4xx401UnauthorizedНет валидной аутентификации или она не пройдена.
4xx402Payment RequiredЗарезервированный код, обычно не используется в обычных API.
4xx403ForbiddenЗапрос понятен, но операция запрещена.
4xx404Not FoundЗапрошенный ресурс не найден.
4xx405Method Not AllowedДля ресурса не поддерживается указанный HTTP-метод.
4xx406Not AcceptableСервер не может отдать ответ в формате из Accept.
4xx407Proxy Authentication RequiredСначала нужна аутентификация у прокси.
4xx408Request TimeoutСервер не дождался запроса в допустимое время.
4xx409ConflictКонфликт с текущим состоянием ресурса.
4xx410GoneРесурс удалён и более недоступен.
4xx411Length RequiredОтсутствует обязательный заголовок Content-Length.
4xx412Precondition FailedУсловие в precondition-заголовках не выполнено.
4xx413Request Too LargeТело запроса превышает лимит сервера.
4xx414Request-URI Too LongURI слишком длинный для обработки сервером.
4xx415Unsupported Media TypeНеподдерживаемый тип данных запроса.
4xx416Range Not SatisfiableНевозможно отдать запрошенный диапазон байтов.
4xx417Expectation FailedСервер не может выполнить требования заголовка Expect.
5xx500Internal Server ErrorОбщая внутренняя ошибка сервера.
5xx501Not ImplementedСервер не поддерживает запрошенный метод/поведение.
5xx502Bad GatewayШлюз/прокси получил некорректный ответ от upstream-сервиса.
5xx503Service UnavailableСервис временно недоступен (перегрузка/обслуживание).
5xx504Gateway TimeoutШлюз/прокси не дождался своевременного ответа от upstream.
5xx505HTTP Version Not SupportedВерсия HTTP в запросе не поддерживается.
5xx511Network Authentication RequiredДля доступа к сети требуется аутентификация.

Практический сценарий

В платёжном API конфликт повторной операции в одном endpoint-е возвращал 409, а в другом — 200 с полем success=false. Из-за этого мобильный клиент в части случаев считал операцию успешной и не показывал пользователю ошибку повторного платежа. После унификации статусов и error-format поведение стало предсказуемым: клиент корректно отличает успех от конфликта, а мониторинг начал показывать реальную картину проблем.

Quiz

Проверьте, что вы усвоили

Авторизуйтесь чтоб пройти тесты