Stage 4. Response Status Codes
HTTP-статус — это короткий сигнал о результате запроса, который клиент получает раньше, чем читает тело ответа. Для API это критично: по коду решения принимают мобильные приложения, frontend, ретраи, мониторинг и алерты. Поэтому статус-код — часть контракта API, а не второстепенная деталь.
1. Базовая логика групп кодов
Удобно помнить три группы, которые покрывают почти всю практику:
2xx: запрос обработан успешно.4xx: проблема в запросе, правах или контексте клиента.5xx: ошибка на стороне сервера.
Эта простая модель уже помогает быстро диагностировать инциденты. Если на дашборде растут 4xx, чаще всего нужно смотреть валидацию, права, клиентские сценарии. Если растут 5xx, это сигнал про стабильность backend-а или зависимостей.
2. Мини-набор кодов, который нужно знать в первую очередь
| Код | Когда использовать | Что должен понять клиент |
|---|---|---|
200 OK | Успешное чтение или обновление с телом ответа | Операция выполнена, можно использовать данные из body |
201 Created | Успешное создание ресурса | Ресурс создан, обычно есть id и/или Location |
204 No Content | Успех без необходимости возвращать body | Операция успешна, обновлять UI можно без чтения данных |
400 Bad Request | Некорректный формат запроса | Запрос нужно исправить технически |
401 Unauthorized | Нет валидной аутентификации | Нужно войти заново или обновить токен |
403 Forbidden | Пользователь аутентифицирован, но прав не хватает | Повторный логин не поможет, нужны другие права |
404 Not Found | Ресурс не найден | Объекта не существует или недоступен по этому пути |
409 Conflict | Конфликт состояния ресурса | Операция логически конфликтует с текущим состоянием |
422 Unprocessable Entity | Формат корректный, но нарушены бизнес-правила | Нужно исправить значения полей по правилам домена |
500 Internal Server Error | Непредвиденный сбой сервера | Проблема на backend, клиент обычно не может исправить |
Для стартового курса этого набора достаточно. Не нужно запоминать десятки редких кодов, пока не появится конкретная прикладная задача.
3. Разница между похожими кодами, где чаще всего ошибаются
401 и 403 путают чаще всего. 401 означает проблему с аутентификацией: токен отсутствует, протух или невалиден. 403 означает, что пользователь уже распознан, но ему нельзя выполнять конкретное действие. Это напрямую влияет на UX: в первом случае показываем повторный вход, во втором — сообщение о недостатке прав.
400 и 422 тоже важно разделять. 400 — запрос «сломанный» технически: неверный JSON, неверный тип, отсутствует обязательная структура. 422 — JSON корректный, но бизнес-правило нарушено, например пароль слишком короткий или дата окончания раньше даты начала.
4. Статус и тело ошибки должны работать вместе
Код ответа даёт класс проблемы, а тело — детали, которые нужны человеку и программе.
{
"error": "validation_failed",
"message": "password is too weak",
"fields": {
"password": "min 12 chars, at least one digit"
},
"traceId": "c92ab1d4"
}
Если структура ошибок единая для всех endpoint-ов, клиенты пишут один универсальный обработчик, а не набор исключений под каждую ручку.
5. Почему схема «всегда 200» вредна
Иногда делают 200 OK для любых результатов и добавляют в body поле вроде success=false. Это кажется простым, но ломает протокол: мониторинг считает ошибку успехом, ретраи работают не по правилам, а клиентам приходится парсить кастомную логику вместо стандартного HTTP-поведения. В реальных системах это повышает сложность и стоимость поддержки.
6. Практический сценарий: регистрация пользователя
Рассмотрим один и тот же endpoint POST /users:
- Валидный запрос, пользователь создан: возвращаем
201 Created. - Email уже занят: возвращаем
409 Conflict. - Email в неверном формате или пароль не проходит правила: возвращаем
422 Unprocessable Entity. - JSON поломан синтаксически: возвращаем
400 Bad Request. - База недоступна: возвращаем
500 Internal Server Error.
В этом сценарии каждый код отражает отдельный класс проблемы, и клиент точно понимает, что делать: попросить исправить поля, показать «email уже занят», предложить повторить позже или инициировать повторную авторизацию.
7. Проверочный список перед релизом endpoint-а
- Для каждого основного сценария выбран отдельный и логичный статус?
- Есть ли чёткая граница между
400и422? - Различаются ли
401и403в соответствии с правилами доступа? - Единый ли формат тела ошибки во всех ручках?
- Проверено ли автотестами, что статус не меняется случайно при рефакторинге?