Какие HTTP статус коды вы знаете?
HTTP статус-коды — это трёхзначные числа, которые сервер возвращает клиенту, чтобы сообщить о результате запроса.
Junior Level
HTTP статус-коды — это трёхзначные числа, которые сервер возвращает клиенту, чтобы сообщить о результате запроса.
Первая цифра — категория: 2 = всё хорошо, 4 = проблема на вашей стороне (клиент), 5 = проблема на нашей стороне (сервер). Это помогает автоматически обрабатывать ошибки.
Классы статус-кодов:
| Класс | Диапазон | Значение |
|---|---|---|
| 1xx | 100-199 | Информационные |
| 2xx | 200-299 | Успех |
| 3xx | 300-399 | Перенаправление |
| 4xx | 400-499 | Ошибка клиента |
| 5xx | 500-599 | Ошибка сервера |
Самые распространённые коды:
| Код | Название | Описание |
|---|---|---|
| 200 | OK | Запрос выполнен успешно |
| 201 | Created | Ресурс создан |
| 204 | No Content | Успех, без тела ответа |
| 301 | Moved Permanently | Ресурс перемещён навсегда |
| 302 | Found | Временное перенаправление |
| 400 | Bad Request | Некорректный запрос |
| 401 | Unauthorized | Не авторизован (нужен логин) |
| 403 | Forbidden | Запрещено (нет прав) |
| 404 | Not Found | Не найдено |
| 500 | Internal Server Error | Внутренняя ошибка сервера |
| 503 | Service Unavailable | Сервис недоступен |
Middle Level
2xx: Success
- 201 Created: Возвращайте с заголовком
Location - 202 Accepted: Для систем на основе очередей. “Я принял задачу, ID такой-то, результат будет позже”
- 204 No Content: Идеально для
DELETEиPUT. Экономит трафик — тело ответа отсутствует
3xx: Redirection
- 304 Not Modified: Ключ к производительности. Используется при Conditional GET (с
If-None-Match). Сервер не шлёт тело - 307 Temporary Redirect / 308 Permanent Redirect: В отличие от 301/302, эти коды гарантируют, что HTTP-метод не изменится (POST останется POST)
// 301/302 исторически разрешали браузеру менять POST на GET при редиректе.
// 307/308 введены, чтобы строго сохранить метод — критично для REST API.
4xx: Client Error
- 401 vs 403: 401 — нет аутентификации (Identity unknown), 403 — нет прав (Identity known, but access denied)
- 409 Conflict: При нарушении бизнес-логики (дубликат email) или конфликте версий в Optimistic Locking
- 422 Unprocessable Entity: Стандарт для ошибок валидации (RFC 4918)
400 = “я не понял ваш запрос” (синтаксическая ошибка, malformed JSON). 422 = “я понял запрос, но данные не проходят валидацию” (email без @, пароль < 8 символов). Клиент по коду понимает: надо исправить данные, а не формат запроса.
- 429 Too Many Requests: Сигнал от Rate Limiter. Всегда добавляйте заголовок
Retry-After
5xx: Server Error
- 502 Bad Gateway: Проблема “соседа”. Nginx не смог достучаться до Java-приложения
- 503 Service Unavailable: Сервер перегружен или на обслуживании. Балансировщики должны исключить узел из ротации
- 504 Gateway Timeout: Бэкенд (Java) не ответил вовремя прокси-серверу (Nginx)
Диагностика
- Golden Signals: Error Rate — один из четырёх золотых сигналов мониторинга (SRE)
- Log Correlation: Каждая ошибка должна содержать
Trace-ID - HTTP 500 в Java: Как правило, не возвращайте 500 вручную — пусть фреймворк делает это для необработанных исключений. 500 должен означать “что-то пошло не так”, а не “бизнес-логика запретила”.
Senior Level
RFC 7807 (Problem Details)
Современные API (включая Spring Boot 3+) переходят от простых кодов к структурированным ошибкам по RFC 7807 (RFC 9457 заменил RFC 7807 в 2023):
{
"type": "https://example.com/probs/out-of-stock",
"title": "Out of Stock",
"status": 400,
"detail": "Item ID 123 is no longer available",
"instance": "/orders/456"
}
// type — URI с документацией ошибки (машиночитаемый)
// title — короткое описание для разработчика
// status — дублирует HTTP код
// detail — человекочитаемое объяснение
// instance — URI конкретного запроса (для логов)
Highload и балансировка
В высоконагруженных системах правильный код ответа критичен для работы балансировщиков (L7 Load Balancers), которые на основе этих кодов принимают решение о “здоровье” (Health Check) сервиса.
Negative Caching
CDN (например, Cloudflare) могут кешировать ответы 404 или 500, чтобы защитить бэкенд от “шторма запросов” к несуществующим ресурсам.
Circuit Breaker
Если микросервис начинает сыпать 5xx кодами, вышестоящий сервис должен сработать по паттерну Circuit Breaker, чтобы не “добить” умирающий инстанс.
Иерархия и Senior-нюансы
- 307/308 гарантируют сохранение метода, в отличие от 301/302 (могут изменить POST на GET)
- 422 предпочтительнее 400 для ошибок валидации — более семантичен
- 429 всегда должен сопровождаться
Retry-Afterдля корректного поведения клиентов - 500 — это всегда баг приложения, а не бизнес-ошибка. Для предсказуемых ошибок бизнеса используйте 4xx
Мониторинг
- Ошибки (Error Rate) — один из четырёх золотых сигналов SRE
- Каждая ошибка должна содержать
Trace-IDдля восстановления цепочки вызовов - Отслеживайте гистограммы задержек (P99) в разрезе методов (GET vs POST)
🎯 Шпаргалка для интервью
Обязательно знать:
- 5 классов статус-кодов: 1xx (информационные), 2xx (успех), 3xx (редирект), 4xx (ошибка клиента), 5xx (ошибка сервера)
- 200 OK, 201 Created (с заголовком Location), 202 Accepted (для асинхронных задач), 204 No Content (для DELETE/PUT)
- 301/302 могут менять POST на GET; 307/308 гарантируют сохранение метода
- 400 = «я не понял запрос» (malformed JSON), 422 = «данные не проходят валидацию»
- 401 = не аутентифицирован (кто вы?), 403 = нет прав (знаю, но нельзя)
- 409 Conflict — дубликат или конфликт версий; 429 Too Many Requests — rate limit
- 500 = баг приложения, 502 = бэкенд не отвечает, 503 = перегружен/обслуживание, 504 = тайм-аут бэкенда
- RFC 9457 (Problem Details) — стандартный JSON для ошибок: type, title, status, detail, instance
Частые уточняющие вопросы:
- Когда использовать 422 вместо 400? — 422 для ошибок валидации данных, 400 для синтаксических ошибок запроса
- Почему 307/308 важнее 301/302 для REST API? — 307/308 сохраняют HTTP-метод при редиректе
- Зачем нужен 202 Accepted? — Для асинхронных задач: «принял, обработаю позже»
- Почему 500 — это всегда баг? — 500 означает непредвиденную ошибку; бизнес-ошибки должны быть 4xx
Красные флаги (НЕ говорить):
- «400 и 422 — одно и то же» — 400 = malformed запрос, 422 = данные невалидны
- «301/302 сохраняют метод при редиректе» — они могут менять POST на GET, 307/308 — нет
- «500 — нормальный ответ для бизнес-ошибок» — бизнес-ошибки = 4xx, 500 = непредвиденный баг
- «401 и 403 — одно и то же» — 401 = не знаю кто вы, 403 = знаю, но нет прав
Связанные темы:
- [[В чём разница между 401 и 403]]
- [[Что такое REST]]
- [[Что такое RESTful API дизайн]]
- [[Как правильно именовать REST endpoints]]
- [[Что такое Accept header]]