Які HTTP статус коди ви знаєте
Перша цифра визначає клас відповіді:
🟢 Junior Level
HTTP статус-код (Status Code) — це тризначне числове значення, яке сервер надсилає у стартовому рядку відповіді клієнту для сповіщення про результат обробки запиту.
Перша цифра визначає клас відповіді:
| Клас | Категорія | Значення |
|---|---|---|
1xx |
Інформаційні (Informational) | Запит отримано, обробка триває (напр. 100 Continue). |
2xx |
Успіх (Success) | Дія успішно прийнята, зрозуміла та оброблена. |
3xx |
Перенаправлення (Redirection) | Для завершення запиту клієнту необхідно виконати додаткові дії. |
4xx |
Помилка клієнта (Client Error) | Запит містить синтаксичну помилку або не може бути виконаний з вини клієнта. |
5xx |
Помилка сервера (Server Error) | Сервер зіткнувся з непередбаченою помилкою під час обробки коректного запиту. |
Базові статус-коди, які зобов’язаний знати кожен розробник
200 OK: Стандартна відповідь у разі успішного виконання запиту (зазвичай містить тіло відповіді).201 Created: Ресурс успішно створено (наприклад, у відповідь наPOST). Сервер зазвичай повертає заголовокLocationз URI нового ресурсу.204 No Content: Запит виконано успішно, але тіло відповіді навмисно відсутнє (типово дляDELETEабоPUT).301 Moved Permanently: Ресурс назавжди переміщено на новий URL.302 Found: Тимчасове перенаправлення на інший URL.400 Bad Request: Некоректний синтаксис запиту (пошкоджений JSON, неприпустимий формат даних).401 Unauthorized: Користувач не аутентифікований (сервер не знає, хто звертається; потрібен заголовокAuthorization).403 Forbidden: Користувач аутентифікований, але в нього немає прав доступу до ресурсу.404 Not Found: Запитаний ресурс не знайдено на сервері.500 Internal Server Error: Непередбачений виняток або збій у коді застосунку на боці сервера.503 Service Unavailable: Сервер тимчасово не може обробити запит (перевантаження, планове технічне обслуговування).
🟡 Middle Level
Розмежування кодів та протокольні нюанси (RFC 9110)
1. Успішні відповіді (2xx)
202 Accepted: Запит прийнято на обробку, проте вона ще не завершена. Застосовується в асинхронних архітектурах (черги повідомлень, фонові задачі). Клієнт отримує ідентифікатор завдання для подальшої перевірки статусу.206 Partial Content: Сервер повертає лише частину вмісту ресурсу (використовується під час дозавантаження файлів та відеотрансляцій за заголовкомRange).
2. Перенаправлення (3xx): Революція 307 та 308
Історично браузери помилково трансформували метод POST у GET після отримання редиректів 301 та 302.
Для усунення цієї проблеми до специфікації було введено суворі коди:
303 See Other: Прямо приписує клієнту виконатиGETна новий URL (основа патерну Post/Redirect/Get).307 Temporary Redirect: Тимчасове перенаправлення, що суворо зберігає вихідний HTTP-метод і тіло (POST залишається POST).308 Permanent Redirect: Постійне перенаправлення, що суворо зберігає HTTP-метод і тіло.304 Not Modified: Відповідь на умовний запит (If-None-MatchабоIf-Modified-Since). Тіло відповіді відсутнє, клієнт бере дані з локального кешу (економія трафіку та часу).
3. Помилки клієнта (4xx)
401 vs 403:401 Unauthorizedзобов’язаний містити заголовокWWW-Authenticate. Означає: «Ви не підтвердили свою особу».403 Forbidden: особа підтверджена, але доступ (RBAC/ABAC) заборонено. Повтор запиту з тими самими обліковими даними марний.
400 vs 422:400 Bad Request: сервер не зміг розпарсити запит (синтаксичний збій, невалідний JSON, некоректне кодування).422 Unprocessable Content(раніше Entity): синтаксис JSON коректний, проте порушено бізнес-правила або валідацію полів (Bean Validation, наприклад, від’ємний вік або некоректний email).
409 Conflict: Конфлікт стану даних (спроба реєстрації вже наявного email, конфлікт унікального індексу або Optimistic Lock).410 Gone: Ресурс існував на сервері, але був навмисно та назавжди видалений без надання адреси перенаправлення.412 Precondition Failed: Не пройдено перевірку умовного заголовка (If-Matchпід час оптимістичного блокування).415 Unsupported Media Type: Сервер не підтримує формат даних, переданий у заголовкуContent-Type(наприклад, надіслано XML замість JSON).429 Too Many Requests: Спрацював Rate Limiter. Сервер зобов’язаний передати заголовокRetry-After: <seconds>.
4. Помилки сервера (5xx)
502 Bad Gateway: Проксі-сервер (NGINX / Envoy / Cloudflare) отримав некоректну відповідь або розрив TCP-з’єднання від бекенду (Java-застосунку).503 Service Unavailable: Бекенд тимчасово недоступний (переповнення пулу потоків Tomcat, сервіс на обслуговуванні).504 Gateway Timeout: Бекенд не відповів проксі-серверу за відведений час (таймаутproxy_read_timeout).
🔴 Senior Level
Стандартизація помилок: RFC 9457 (Problem Details for HTTP APIs)
Повернення довільних JSON-структур під час помилок ({"error": "bad request", "code": 12}) визнано антипатерном.
Сучасним індустріальним стандартом є RFC 9457 (який замінив RFC 7807), нативно вбудований у Spring Boot 3+ через клас ProblemDetail (Content-Type: application/problem+json).
{
"type": "https://api.example.com/errors/insufficient-funds",
"title": "Insufficient Funds",
"status": 422,
"detail": "Your balance of 1500 USD is insufficient for debiting 2000 USD",
"instance": "/api/v1/accounts/101/debit",
"timestamp": "2026-09-26T08:30:00Z",
"traceId": "9b1deb4d3b7d4bad9bdd2b0d7b3dcb6d"
}
Production-ready обробник помилок на Spring Boot 3
package com.example.exception;
import org.springframework.http.HttpStatus;
import org.springframework.http.ProblemDetail;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import java.net.URI;
import java.time.Instant;
import java.util.Map;
import java.util.stream.Collectors;
@RestControllerAdvice
public class GlobalExceptionHandler {
// 1. Помилки валідації DTO -> 422 Unprocessable Content
@ExceptionHandler(MethodArgumentNotValidException.class)
public ProblemDetail handleValidationException(MethodArgumentNotValidException ex) {
ProblemDetail problem = ProblemDetail.forStatusAndDetail(
HttpStatus.UNPROCESSABLE_ENTITY,
"Validation failed for one or more fields"
);
problem.setTitle("Unprocessable Content");
problem.setType(URI.create("https://api.example.com/errors/validation"));
problem.setProperty("timestamp", Instant.now());
Map<String, String> invalidFields = ex.getBindingResult().getFieldErrors().stream()
.collect(Collectors.toMap(
FieldError::getField,
fe -> fe.getDefaultMessage() != null ? fe.getDefaultMessage() : "Invalid value",
(existing, replacement) -> existing
));
problem.setProperty("invalidFields", invalidFields);
return problem;
}
// 2. Бізнес-конфлікт -> 409 Conflict
@ExceptionHandler(UserAlreadyExistsException.class)
public ProblemDetail handleUserExistsException(UserAlreadyExistsException ex) {
ProblemDetail problem = ProblemDetail.forStatusAndDetail(
HttpStatus.CONFLICT,
ex.getMessage()
);
problem.setTitle("Resource Conflict");
problem.setType(URI.create("https://api.example.com/errors/user-conflict"));
problem.setProperty("timestamp", Instant.now());
return problem;
}
// 3. Непередбачені помилки -> 500 Internal Server Error (без витоку stack trace!)
@ExceptionHandler(Exception.class)
public ProblemDetail handleGenericException(Exception ex) {
ProblemDetail problem = ProblemDetail.forStatusAndDetail(
HttpStatus.INTERNAL_SERVER_ERROR,
"An unexpected internal error occurred. Please contact support."
);
problem.setTitle("Internal Server Error");
problem.setType(URI.create("https://api.example.com/errors/internal"));
problem.setProperty("timestamp", Instant.now());
return problem;
}
}
Highload, Observability та вплив кодів на інфраструктуру
- Negative Caching у CDN / Edge:
- Відповіді
404 Not Foundможуть кешуватися в CDN (Cloudflare) на короткий час (наприклад, 10 секунд), щоб захистити бекенд від сканування ботами та DDoS-атак.
- Відповіді
- Circuit Breaker (Resilience4j / Envoy):
- Circuit Breaker налаштовується на відсоток відповідей
5xx(включно з502,503,504). Помилки4xxкласифікуються як штатні помилки клієнтів і не повинні призводити до розмикання ланцюга.
- Circuit Breaker налаштовується на відсоток відповідей
- Observability (SRE Golden Signals):
- Метрики
http_server_requests_seconds_count{status=~"5.."}активують алерти в PagerDuty, оскільки500означає дефект у коді бекенду, тоді як сплеск429вказує на необхідність перегляду лімітів Rate Limiter.
- Метрики
🎯 Шпаргалка для інтерв’ю
30-секундна відповідь
HTTP статус-коди поділяються на 5 класів:
- 1xx: Інформаційні (
100 Continue).- 2xx: Успіх:
200 OK,201 Created(із заголовкомLocation),202 Accepted(асинхронні задачі),204 No Content(успіх без тіла).- 3xx: Редиректи:
301/302(історичні),303 See Other(патерн PRG),304 Not Modified(кеш),307/308(суворо зберігають метод і тіло).- 4xx: Помилки клієнта:
400(синтаксис),401(немає аутентифікації, обов’язковийWWW-Authenticate),403(немає прав),404(не знайдено),409(конфлікт даних/версій),412(конфлікт ETag),422(помилки валідації полів),429(Rate limit ізRetry-After).- 5xx: Помилки сервера:
500(баг у коді),502(збій бекенду за NGINX),503(перевантаження сервісу),504(таймаут відповіді бекенду).У сучасному REST API формат помилок стандартизується за RFC 9457 Problem Details.
4 каверзних питання з відповідями
-
У чому різниця між статус-кодами 302 Found та 307 Temporary Redirect? Відповідь: Історично браузери під час отримання коду
302 Foundтрансформували методPOSTуGET. Код307 Temporary Redirectсуворо специфікований у RFC 9110: клієнт зобов’язаний повторити перенаправлений запит з тим самим HTTP-методом і тілом, що є критичним для безпеки мутуючих операцій у REST API. -
Коли слід повертати 400 Bad Request, а коли 422 Unprocessable Content? Відповідь:
400 Bad Requestповертається у разі синтаксичних помилок, коли сервер у принципі не зміг розпарсити запит (битий JSON, неприпустимий заголовок чи кодування).422 Unprocessable Contentповертається, коли синтаксис коректний, але порушено семантику даних (помилки валідації полів, порожні обов’язкові параметри, порушення бізнес-правил). -
Чому код 500 не повинен використовуватися для бізнес-помилок (наприклад, недостатньо коштів на рахунку)? Відповідь: Статуси
5xxсигналізують про збій інфраструктури або необроблене виключення в коді (баг). Інфраструктурний моніторинг (SRE, Prometheus, Circuit Breaker) реагує на5xxрозмиканням ланцюга та викликом чергових інженерів. Для очікуваних відмов бізнес-логіки необхідно повертати коди4xx(409 Conflict,422 Unprocessable Content). -
Що обов’язково повинна містити відповідь сервера зі статусом 401 Unauthorized за стандартом HTTP? Відповідь: За специфікацією RFC 9110 (розділ 15.5.2) відповідь із кодом
401 Unauthorizedзобов’язана містити заголовок відповідіWWW-Authenticate, який вказує щонайменше одну підтримувану схему аутентифікації (наприклад,WWW-Authenticate: Bearer realm="api").
Червоні прапорці (чого категорично не можна говорити)
- ❌ «401 і 403 — це синоніми» (401 — невідома особа користувача, 403 — особа відома, але доступ заборонено політикою прав).
- ❌ «Якщо в БД немає запису за ID, контролер повинен падати з 500 помилкою» (відсутність даних за ID клієнта — це штатна ситуація
404 Not Found). - ❌ «Для бізнес-помилок завжди повертаємо 200 OK, а статус пишемо всередині JSON» (антипатерн SOAP/RPC, що ламає HTTP-кешування, балансування та моніторинг метрик).
- ❌ «Код 204 No Content повертає порожній JSON-рядок “{}”» (код 204 гарантує фізичну відсутність тіла відповіді, розмір
Content-Length: 0).