Клиент API получает одинаковый ответ для постоянной ошибки валидации и временного сбоя зависимости. Какой принцип контракта позволит различать их обработку?
Контракт API должен явно различать исправимые клиентом ошибки и временные сбои инфраструктуры. Для этого используют подходящий HTTP-статус вместе со стабильным машинным кодом ошибки: клиентская ошибка должна приводить к исправлению запроса, а временная — допускать ограниченную повторную попытку.
Одного текста сообщения недостаточно: он предназначен для человека и не должен определять алгоритм клиента.
В распределённых системах ошибки часто возникали на сетевых границах: зависимость могла быть недоступна, отвечать слишком долго или временно перегружаться. Ранние интеграции нередко возвращали один общий ответ вроде «операция не выполнена», из-за чего клиенты не могли понять, нужно ли менять запрос или повторять его.
Такое различие стало частью практики проектирования HTTP-контрактов. Статус ответа даёт общий класс проблемы, а машинный код и дополнительные поля уточняют причину и ожидаемое действие клиента.
Ошибка валидации постоянна, пока клиент не изменит данные. Повторная отправка такого запроса бесполезна и может создавать лишнюю нагрузку.
Сбой зависимости, напротив, может исчезнуть через несколько секунд. Если клиент воспримет его как окончательную ошибку, пользовательская операция будет потеряна; если начнёт безусловно повторять ошибочный запрос, возникнут лишняя нагрузка, лавина повторов и риск повторного выполнения операции.
Сначала ошибку классифицируют по ожидаемому действию клиента:
validation_error или более конкретный код поля.dependency_unavailable.В теле ошибки полезно передавать машинный код, понятное сообщение, сведения о проблемных полях и идентификатор корреляции. Машинный код должен быть стабильным: изменение текста сообщения не должно ломать обработку клиента.
Подсказка о повторе не является гарантией успеха. Клиент должен применять ограниченное число попыток, задержку с увеличением интервала и верхний предел времени; повторять можно только если операция допускает безопасное повторное выполнение или контракт определяет способ устранения неопределённого результата.
Разделение ошибок не означает, что каждый временный сбой можно повторять. Например, тайм-аут после отправки запроса не всегда означает, что сервер его не обработал. Поэтому контракт должен учитывать не только техническую причину, но и состояние операции для клиента.
Платёжный сервис получает запрос на создание платежа. В одном случае сумма отрицательна, в другом платёжный шлюз временно недоступен. Изначально оба случая возвращали один ответ с признаком неуспеха.
Рассматривались два варианта. Возвращать только текстовую причину было просто, но ненадёжно: формулировки могли измениться, а локализация ломала бы разбор. Возвращать только разные HTTP-статусы лучше разделяло случаи, но не давало достаточно устойчивой детализации для автоматической обработки.
Выбрали комбинацию статуса и машинного кода: ошибка суммы стала постоянной ошибкой запроса, а недоступность шлюза — временной ошибкой зависимости. Клиент перестал повторять некорректные платежи, а временные сбои обрабатывал ограниченным числом попыток с журналированием и последующей проверкой состояния платежа. Это снизило лишнюю нагрузку и уменьшило число потерянных операций.
Нет. Статус полезен как общий сигнал, но часто описывает только класс проблемы. Один и тот же класс может включать разные причины и разные действия клиента: например, исправление конкретного поля, повтор после задержки или обращение в поддержку. Поэтому стабильный машинный код нужен для программной логики, а HTTP-статус — для совместимого общего поведения.
Нет. Серверский статус указывает, что проблема находится не только в синтаксисе запроса, но не гарантирует временный характер сбоя. Повтор допустим лишь при наличии признаков временности, ограниченной политике попыток и понимании последствий повторного выполнения. Для неизвестного результата особенно важно проверить состояние операции, а не слепо создавать её заново.
Нет. Сетевой сбой может скрывать уже выполненную операцию, а ответ зависимости может содержать окончательный бизнес-отказ. Нужно различать как минимум постоянный отказ по бизнес-правилам, временную недоступность и неопределённый результат. Для последнего контракт должен предусматривать запрос состояния, ключ операции или другой способ безопасно установить итог, иначе автоматический повтор может привести к дублированию действия.