Обработка ошибок REST API: статус-коды и объекты ошибок
Хорошая обработка ошибок в REST API помогает разработчикам быстро понять проблему, локализовать её и исправить, без лишних догадок.
Краткое описание
Обработка ошибок REST API описывает то, как интерфейс реагирует на некорректные запросы, технические сбои и нарушения бизнес-логики. Это включает правильный HTTP-статус-код, структурированный ответ об ошибке и уникальную идентификацию ошибки. RFC 7807 определяет стандартный формат Problem Details для ответов об ошибках с полями type, title, status, detail и instance. Хорошая обработка ошибок консистентна на всех эндпоинтах, содержит достаточно информации для разработчика и не раскрывает критичные детали системы. Она снижает нагрузку на поддержку, улучшает опыт разработчика и позволяет клиентам автоматически классифицировать ошибки и реагировать соответствующим образом.
Когда работаешь с API, серверные ошибки становятся твоим главным противником. Возьми, к примеру, сервис с лимитами на токены и запросы, а ещё он использует Cloudflare, у которого свои лимиты и правила. Если твои запросы обрабатываются не полностью или кажется, что только спорадически, то правильный дебаг критичен. Какой отклик приходит и что он означает.
Важные компоненты
Правильные HTTP-статус-коды
HTTP-статус-коды это первая информация, которую клиент получает об успехе или неудаче запроса. Коды 4xx указывают на ошибки клиента, коды 5xx на ошибки сервера. Важные коды 4xx это 400 Bad Request, 401 Unauthorized, 403 Forbidden, 404 Not Found, 409 Conflict, 422 Unprocessable Content и 429 Too Many Requests. Коды 5xx как 500 Internal Server Error, 502 Bad Gateway и 503 Service Unavailable указывают на проблемы на стороне сервера.
Problem Details по RFC 7807
RFC 7807 определяет стандартный формат для ответов об ошибках. Problem Detail содержит минимум type, title, status и detail. Опционально можно добавить instance для ошибочного URI и другие расширения. Content-Type это application/problem+json. Формат позволяет клиентам единообразно парсить и отображать ошибки.
Уникальные идентификаторы ошибок
Каждый ответ об ошибке должен содержать уникальный идентификатор ошибки, например UUID или correlation ID. Это позволяет отследить ошибку в логах и системах мониторинга без раскрытия внутренних деталей. Клиент может предоставить этот идентификатор в support.
Категории и коды ошибок
Помимо HTTP-статус-кодов, ответы об ошибках должны содержать специфичные для приложения коды ошибок. Код вроде ORDER_NOT_FOUND или PAYMENT_DECLINED более точен, чем общий 404. Такие коды помогают клиентам целенаправленно реагировать на конкретные ситуации.
Ошибки валидации
При ошибках валидации ответ должен указать, какие поля ошибочные и почему. Например: field: email, message: Неверный формат электронной почты. Это позволяет исправить формы на клиенте напрямую.
Ошибки без раскрытия внутренних деталей
Сообщения об ошибках должны быть достаточно информативны, но не содержать внутренние пути, stacktrace или детали БД. Такая информация может помочь злоумышленникам. Внутренние детали принадлежат логам, не API-ответу.
Локализация и язык
Сообщения об ошибках могут зависеть от языка. Клиент должен указать через заголовок Accept-Language, какой язык он ожидает. Сервер отвечает соответственно локализованными сообщениями, если они доступны.
Информация о повторе
При временных ошибках вроде 429 или 503 сервер должен указать через заголовок Retry-After, когда клиент может повторить запрос. Это предотвращает необдуманные повторения и снижает нагрузку на сервер.
Логирование и мониторинг
Каждая ошибка должна логироваться серверной стороной с контекстом, включая Request-ID, временную метку, эндпоинт, статус-код и детали ошибки. Системы мониторинга могут на основе этого выдавать алерты и выявлять тренды ошибок.
Консистентность на всех эндпоинтах
Все эндпоинты API должны использовать одинаковый формат ошибок. Единая структура упрощает реализацию на клиенте и обработку ошибок. Отклонения приводят к ненужному специальному коду и повышенному риску ошибок.
Пример из практики
Клиент отправляет запрос на создание заказа с некорректными данными:
POST /api/v1/orders
Content-Type: application/json
{
"customerId": 123,
"items": [
{ "productId": 42, "quantity": 0 }
]
}
API отвечает с 422 Unprocessable Content и Problem Detail:
HTTP/1.1 422 Unprocessable Content
Content-Type: application/problem+json
X-Request-ID: a1b2c3d4-e5f6-7890-abcd-ef1234567890
{
"type": "https://api.shop.de/problems/validation-error",
"title": "Ошибка валидации",
"status": 422,
"detail": "Заказ содержит некорректные данные.",
"instance": "/api/v1/orders",
"errors": [
{
"field": "items[0].quantity",
"code": "QUANTITY_TOO_LOW",
"message": "Количество должно быть минимум 1."
}
]
}
Клиент сразу видит, какое поле неправильное и почему. X-Request-ID помогает support найти ошибку в логах. Формат ошибки консистентен и машиночитаем.
FAQ: обработка ошибок REST API
1. Что такое Problem Detail по RFC 7807?
2. Почему API должны использовать единообразные форматы ошибок?
3. Что должно быть в ответе об ошибке?
4. В чём разница между 400 и 422?
5. Когда использовать 401 и когда 403?
6. Что такое 409 Conflict?
7. Нужно ли отправлять stacktrace в ответах об ошибках?
8. Что такое correlation ID?
9. Какое преимущество специфичных для приложения кодов ошибок?
10. Что такое 429 Too Many Requests?
11. Как обрабатывать серверные ошибки?
12. Что такое заголовок Retry-After?
13. Должны ли сообщения об ошибках быть локализованы?
14. В чём разница между title и detail?
15. Как тестировать случаи ошибок в API?
Продолжаем путь изучения API, переходим к версионированию
Следующая статья в нашем пути изучения API посвящена версионированию API — стратегиям для REST, GraphQL и gRPC, а также миграции между версиями API.
Источники
- https://www.rfc-editor.org/rfc/rfc7807
- https://www.rfc-editor.org/rfc/rfc9110
- https://opensource.zalando.com/restful-api-guidelines/index.html
Рекомендуемые книги по разработке API
Если ты хочешь глубже погрузиться в обработку ошибок API, проектирование API и архитектуру программного обеспечения, мы рекомендуем эти книги:
Keine Bücher für Kategorie "api-development" gefunden.



