Возврат ошибок в API
От: Буравчик Россия  
Дата: 24.06.19 09:05
Оценка:
Какие HTTP status code используются в ваших API?
200, 401, 403, 404 и т.п.

Передаете ли дополнительную информацию об ошибках? Какую?
Код ошибки, текстовое сообщение, на каком языке (русский, английский), дополнительные параметры?

Кодируете ошибки, как? Единая нумерация для всего API, или свои ошибки для каждого endpoint?

Используете какие-то правила для возвратов ошибок?
Например, по аналогии с JSON-RPC, в котором наличие в ответе поля errors означает, что произошла ошибка при обработке запроса.

Что возвращаете, если клиент запрашивает существующий ресурс, к которому запрещен доступ:
404 или 403?

В общем, научите как надо возвращать информацию об ошибках в API
Best regards, Буравчик
Re: Возврат ошибок в API
От: MadHuman Россия  
Дата: 24.06.19 18:39
Оценка: 92 (3)
Здравствуйте, Буравчик, Вы писали:

Б>Какие HTTP status code используются в ваших API?

если ошибка клиента (неправильный запрос) — 4**. неправильный запрос — это значит что клиенту не следует повторять запрос в том же виде, без изменений.
если сервера — 500 (это перегрузка сервера, неожидаемые ошибки при обработке реквеста). ошибка сервера — это когда запрос составлен верно, но сервер по каким-то причинам не смог.

Б>Передаете ли дополнительную информацию об ошибках? Какую?

если для целей обработки ошибки на клиенте нужна эта доп. информация — передаём.
можно в заголовке, типа X-Reason: какой-то доп. код/идентификатор поясняющий что не так.

Б>Код ошибки, текстовое сообщение, на каком языке (русский, английский), дополнительные параметры?

это зависит. если система (и апи) в основном для русскоязычных — можно на русском.
всё дополнительное определяется конкретикой, если вызвающей стороне нужна/плезна доп. информация о том, что не так — можно включить.

Б>Что возвращаете, если клиент запрашивает существующий ресурс, к которому запрещен доступ:

Б>404 или 403?
403 ближе к сути, но есть нюанс, если надо скрыть что такой ресурс существует (защита от перебора), то можно и 404.

есть практика http использовать в качестве транспорта (аля JSON-RPC), в этом случае ответ всегда 200 и инфа об ошибке в теле ответа.
но наша практика показала, что использование http кодов ответа тоже норм, особенно с учетом, что их в любом случае придется обрабатывать (может оказаться реально плохой запрос, прокси, и прочее)
то лучше тогда уж сразу на них ориентироваться. бытует мнение что кодов недостаточно (это так), но если в хидере или теле возвращать доп. информацию (если надо), то всё ок.

также использование хттп статус кодов, упрощает анализ логов веб-сервера. сразу можно фильтровать ошибки, иначе придется что-то дополнительно мутить.
Отредактировано 24.06.2019 18:41 MadHuman . Предыдущая версия .
Re: Возврат ошибок в API
От: vsb Казахстан  
Дата: 24.06.19 18:48
Оценка: -2
Последний раз использовал код 400 и возврат кода ошибки в читаемом виде например user not found с типом text/plain. Минус в том, что сервер в определённых условиях тоже возвращает код 400. Поэтому хочу переделать на какой-нибудь другой код из разряда 4xx, пока не выбрал, какой (большого значения не имеет, лишь бы не пересекался со стандартными кодами, которые может отдавать сервер).

Считаю пересечение неудачной идеей. 404 например отдавать не стоит, чтобы клиент мог чётко отличить кривую конфигурацию сервера от "правильного" ошибочного ответа. Хотя народу вроде нравится...
Re[2]: Возврат ошибок в API
От: Stalker. Австралия  
Дата: 24.06.19 23:28
Оценка:
Здравствуйте, vsb, Вы писали:

vsb>Считаю пересечение неудачной идеей. 404 например отдавать не стоит, чтобы клиент мог чётко отличить кривую конфигурацию сервера от "правильного" ошибочного ответа. Хотя народу вроде нравится...


семантически отсутствие пользователя users/99 равнозначно неверному адресу usrs/99, плюс в теле ответа будет сообщение, по которому можно понять что именно отсутствует
Re[3]: Возврат ошибок в API
От: vsb Казахстан  
Дата: 25.06.19 03:24
Оценка:
Здравствуйте, Stalker., Вы писали:

vsb>>Считаю пересечение неудачной идеей. 404 например отдавать не стоит, чтобы клиент мог чётко отличить кривую конфигурацию сервера от "правильного" ошибочного ответа. Хотя народу вроде нравится...


S>семантически отсутствие пользователя users/99 равнозначно неверному адресу usrs/99


Не согласен. Если я забыл задеплоить варку, у меня внезапно куда-то исчезли все юзеры? Не так ведь. Это как я на RSDN зайду, а мне напишут, что тема не существует, вместо того, чтобы написать, что форум перезагружают.

S>плюс в теле ответа будет сообщение, по которому можно понять что именно отсутствует


Ну т.е. предлагается анализировать не код ответа, а тело ответа? Но от этого же хочется уйти вроде как.
Re: Возврат ошибок в API
От: RushDevion Россия  
Дата: 25.06.19 09:07
Оценка: 180 (9) +1
Здравствуйте, Буравчик, Вы писали:

Б>Какие HTTP status code используются в ваших API?

Б>200, 401, 403, 404 и т.п.
Используем все.
200 (OK) — все OK, в теле ответа будут данные
201 (Created) — все ОК, новая сущность создана. Обычно в ответ на POST, в хидере Location — адрес новой сущности. В теле ответа могут быть данные.
202 (Accepted) — все ОК, мы твой запрос приняли, обработаем позже (e.g. положили в очередь). В теле ответа могут быть данные.
204 (No Content) — все ОК, мы твой запрос обработали, но контент вернуть не можем (обычно в ответе на DELETE)
308 (Permanent Redirect) — мы тут немного поменяли схему роутов, иди в другое место
400 (Bad Request) — с входящим запросом что-то не так (e.g. не прошла валидация, не хватает данных, неправильный формат и т.п.)
401 (Unauthorized) — мы не знаем, кто ты такой, иди авторизуйся
403 (Forbidden) — авторизовался? молодец! Но прав на доступ конкретно к этому ресурсу у тебя все равно не хватает
404 (Not Found) — ресурс не найден
409 (Conflict) — твоя локальная копия данных устарела (обычно для реализации оптимистичной блокировки в ответ на POST/PUT/PATCH)
429 (Too Many Requests) — если есть реализуется какой-то вариант rate-limiting'a
500 (Internal Server Error) — упс, мы где-то облажались. Уже работаем над этим.

Б>Передаете ли дополнительную информацию об ошибках? Какую?

Б>Код ошибки, текстовое сообщение, на каком языке (русский, английский), дополнительные параметры?
Да. Сама модель ошибки в теле запроса, e.g.
{
  "http_code": 403,          // Дублируем тут, для удобства клиента
  "code": "AccountBlocked",   // Код ошибоки.
  "message": "The account 'xxx' is blocked",  // На языке запроса (Accept-хидер), по умолчанию - английский
  "validation_errors": [
     { "field1": "error text1" },
     { "field2": "error text2" }
  ]
}



Б>Кодируете ошибки, как? Единая нумерация для всего API, или свои ошибки для каждого endpoint?

Обычные текстовые строки.
Есть какой-то глобальные набор ошибок (типа аккаунт заблокирован, требуется авторизация, входные данные некорректны и т.п.).
Иногда добавляются endpoint-специфичные.

Б>Используете какие-то правила для возвратов ошибок?

Б>Например, по аналогии с JSON-RPC, в котором наличие в ответе поля errors означает, что произошла ошибка при обработке запроса.
Есть JSON/XML-схема для кода ошибки.
Она описывается в SWAGGER-документации.

Б>Что возвращаете, если клиент запрашивает существующий ресурс, к которому запрещен доступ:

Б>404 или 403?
403

Б>В общем, научите как надо возвращать информацию об ошибках в API

Так, чтобы клиентам твоего API было удобно ей пользоваться
Re: Возврат ошибок в API
От: Ночной Смотрящий Россия  
Дата: 25.06.19 12:44
Оценка: 14 (1)
Здравствуйте, Буравчик, Вы писали:

Б>Какие HTTP status code используются в ваших API?

Б>200, 401, 403, 404 и т.п.

Много разных. Помимо перечисленных точно используется 201, 202, 400, 409, 500.

Б>Передаете ли дополнительную информацию об ошибках?


Да.

Б> Какую?


Уникальный код, severity, источник, нелокализуемое сообщение на английском, название параметра если применимо, значения подстановок для локализованного сообщения. В отладочных версиях еще stacktrace.
А вообще есть RFC 7807.

Б>Кодируете ошибки, как? Единая нумерация для всего API, или свои ошибки для каждого endpoint?


Вообще не числа, а символьные коды.

Б>Что возвращаете, если клиент запрашивает существующий ресурс, к которому запрещен доступ:

Б>404 или 403?

403 разумеется.
... << RSDN@Home 1.3.17 alpha 5 rev. 62>>
Re[2]: Возврат ошибок в API
От: Ночной Смотрящий Россия  
Дата: 25.06.19 12:46
Оценка:
Здравствуйте, MadHuman, Вы писали:

MH>если сервера — 500 (это перегрузка сервера


Для перегрузки есть специальный код, 429. И еще желательно хидер Retry-After.
... << RSDN@Home 1.3.17 alpha 5 rev. 62>>
Re[3]: Возврат ошибок в API
От: MadHuman Россия  
Дата: 25.06.19 13:35
Оценка:
Здравствуйте, Ночной Смотрящий, Вы писали:

MH>>если сервера — 500 (это перегрузка сервера

НС>Для перегрузки есть специальный код, 429.
да, но 429 (Too Many Requests) — для более узкого случая, когда хотят на сервере ограничить частоту реквестов от клиента. в этом случае да, лучше его.
я имел ввиду несколько другие ситуации, например для обработки реквеста надо сходить в базу, база перегружена и ответила соотвествующей ошибкой.
или сервер под высокой нагрузкой и реквест клиента по каким-то причинам (особенно связанным с данными клиентам) выполняется слишком долго и его прервали.
или сервер уже под высокой нагрузкой и пока лучше не начинать обработку новых запросов.
типа такого.

НС>И еще желательно хидер Retry-After.
Re[4]: Возврат ошибок в API
От: Ночной Смотрящий Россия  
Дата: 25.06.19 13:45
Оценка: -2
Здравствуйте, MadHuman, Вы писали:

MH>да, но 429 (Too Many Requests) — для более узкого случая


В HTTP RFC ничего про более узкие случаи не сказано.

MH>, когда хотят на сервере ограничить частоту реквестов от клиента. в этом случае да, лучше его.

MH>я имел ввиду несколько другие ситуации, например для обработки реквеста надо сходить в базу, база перегружена и ответила соотвествующей ошибкой.
MH>или сервер под высокой нагрузкой и реквест клиента по каким-то причинам (особенно связанным с данными клиентам) выполняется слишком долго и его прервали.
MH>или сервер уже под высокой нагрузкой и пока лучше не начинать обработку новых запросов.

Не вижу принципиального отличия. Если ты понял что проблема именно в перегруженности — 429 самое то, неважно какой именно компонент перегружен. Потому что реакция клиента во всех случаях одна — попробовать попозже или сказать что сервер перегружен.
... << RSDN@Home 1.3.17 alpha 5 rev. 62>>
Re[5]: Возврат ошибок в API
От: MadHuman Россия  
Дата: 25.06.19 15:53
Оценка: 6 (1)
Здравствуйте, Ночной Смотрящий, Вы писали:

НС>Здравствуйте, MadHuman, Вы писали:


MH>>да, но 429 (Too Many Requests) — для более узкого случая


НС>В HTTP RFC ничего про более узкие случаи не сказано.


в RFC сказано так

The 429 status code indicates that the user has sent too many
requests in a given amount of time ("rate limiting").

The response representations SHOULD include details explaining the
condition, and MAY include a Retry-After header indicating how long
to wait before making a new request.



НС>Не вижу принципиального отличия.

я вижу отличие в следующем — тут проблема из-за клиента, он часто шлет запросы (поэтому и код выбрали 4**).
а в случае перегрузки сервера или какого-то компонента, клиент может быть и не причем.
его может несколько обескуразить, ответ, что это он has sent too many requests in a given amount of time.
ведь он может сделал 1-й реквест.

НС>Потому что реакция клиента во всех случаях одна — попробовать попозже или сказать что сервер перегружен.

для этого норм упомянутый вами ранее хидер Retry-After.
его и для 500 и для 429 стоит смотреть.
Re[5]: Возврат ошибок в API
От: · Великобритания  
Дата: 25.06.19 16:41
Оценка: 4 (1) +6
Здравствуйте, Ночной Смотрящий, Вы писали:

MH>>, когда хотят на сервере ограничить частоту реквестов от клиента. в этом случае да, лучше его.

MH>>я имел ввиду несколько другие ситуации, например для обработки реквеста надо сходить в базу, база перегружена и ответила соотвествующей ошибкой.
MH>>или сервер под высокой нагрузкой и реквест клиента по каким-то причинам (особенно связанным с данными клиентам) выполняется слишком долго и его прервали.
MH>>или сервер уже под высокой нагрузкой и пока лучше не начинать обработку новых запросов.
НС>Не вижу принципиального отличия. Если ты понял что проблема именно в перегруженности — 429 самое то, неважно какой именно компонент перегружен. Потому что реакция клиента во всех случаях одна — попробовать попозже или сказать что сервер перегружен.
Принципиальное отличие, что возвратить 4xx клиенту — обвинить клиента в том, что он что-то делает не так. А 5xx — это что-то не так с сервером.
При перегрузке сервера не по вине данного клиента — надо возвращать 503 Service Unavailable. Собственно это как раз то, что обычно делают в такой ситуации всякие лоад-балансеры и проксяки.
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[6]: Возврат ошибок в API
От: Ночной Смотрящий Россия  
Дата: 25.06.19 17:34
Оценка:
Здравствуйте, ·, Вы писали:

·>Принципиальное отличие, что возвратить 4xx клиенту — обвинить клиента в том, что он что-то делает не так. А 5xx — это что-то не так с сервером.


Чем при этом должна отличаться реакция клиента?
... << RSDN@Home 1.3.17 alpha 5 rev. 62>>
Re[7]: Возврат ошибок в API
От: RushDevion Россия  
Дата: 25.06.19 19:07
Оценка: +1
НС>·>Принципиальное отличие, что возвратить 4xx клиенту — обвинить клиента в том, что он что-то делает не так. А 5xx — это что-то не так с сервером.
НС>Чем при этом должна отличаться реакция клиента?

Главным образом retry-политикой и способом обработки ошибки, e.g.
1) 500 Internal Server Error — заретраиться сразу, но не более 3-х попыток.
Т.к., возможно, ошибка либо разовая (e.g. таймаут сработал, GC невовремя запустился и т.п.), либо случилась на конкретной ноде (если у нас кластер).
Значит, есть шанс, что следующий запрос придет на другую ноду и там все будет хорошо.
Ну а если три раза подряд облом — скорей всего вся система лежит и больше от нее ничего не добьешься.
2) 503 Service Unavailable, 529 To Many Requests — мы вот-вот положим сервер своими запросами, надо бы замедлиться.
Здесь подойдет бесконечный ретрай в рамках общего таймаута, с эспоненциальным ростом времени ожидания между попытками.
Т.е. первый ретрай — через 1сек., потом через 2, потом через 4 и т.д.
3) 4xx — тут ретраиться бесполезно, т.к. ответ не изменится. Остается только обработать ошибку.
400 Bad Request — можно распарсить валидационные ошибки из тела ответа и отобразить их в UI
404 Not Found — показать сообщение "Запись не найдена"
403 Forbidden — показать сообщение "Доступ запрещен", возможно записать в Audit Log
409 Conflict — показать сообщение "Ваша копия данных устарела. Обновить? Да/Нет."
Отредактировано 25.06.2019 19:10 RushDevion . Предыдущая версия .
Re: Возврат ошибок в API
От: KOLRH Финляндия  
Дата: 26.06.19 05:57
Оценка: +1
Здравствуйте, Буравчик, Вы писали:

Б>Какие HTTP status code используются в ваших API?

Б>200, 401, 403, 404 и т.п.
Стараемся использовать все. Зачем придумывать колесо заново и большая часть клиентов умеет их отрабатывать на достаточном уровне.
Хотел бы еще дополнить лист кодом 422 (Unprocessable Entity). Использую когда запрос вроде синтаксически правильный, но логически нет. Например клиент посылает адрес, в котором почтовый код не соответствует городу или улице.

Б>Передаете ли дополнительную информацию об ошибках? Какую?

Б>Код ошибки, текстовое сообщение, на каком языке (русский, английский), дополнительные параметры?
Б>Кодируете ошибки, как? Единая нумерация для всего API, или свои ошибки для каждого endpoint?
Обязательно передаю в теле ответа. Текстовое сообщение на английском для логов и код ошибки, по которому клиент сможет показать ошибку пользователю на желаемом языке.
Нумерация глобальная для общих ошибок, и расширяется ендпойнт-специфичными.

Б>Используете какие-то правила для возвратов ошибок?

Б>Например, по аналогии с JSON-RPC, в котором наличие в ответе поля errors означает, что произошла ошибка при обработке запроса.

Б>Что возвращаете, если клиент запрашивает существующий ресурс, к которому запрещен доступ:

Б>404 или 403?
403

Б>В общем, научите как надо возвращать информацию об ошибках в API

Сами учимся все время
api error
Re[8]: Возврат ошибок в API
От: Ночной Смотрящий Россия  
Дата: 26.06.19 08:24
Оценка:
Здравствуйте, RushDevion, Вы писали:

RD>Главным образом retry-политикой и способом обработки ошибки, e.g.


Речь была не вообще про все коды, а исключительно про 429 vs 500 при перегрузке чего то там внутри сервиса.
... << RSDN@Home 1.3.17 alpha 5 rev. 62>>
Re[4]: Возврат ошибок в API
От: Stalker. Австралия  
Дата: 01.07.19 06:25
Оценка:
Здравствуйте, vsb, Вы писали:

vsb>Не согласен. Если я забыл задеплоить варку, у меня внезапно куда-то исчезли все юзеры? Не так ведь. Это как я на RSDN зайду, а мне напишут, что тема не существует, вместо того, чтобы написать, что форум перезагружают.


не знаю что такое "задеплоить варку", но при "кривой" конфигурации могут легко прийдти и 500-коды, и вообще на практике не требуется клиентам отличать кривую конфигурацию от некривой

vsb>Ну т.е. предлагается анализировать не код ответа, а тело ответа? Но от этого же хочется уйти вроде как.


зачем куда-то уходить от тела ответа? Оно совершенно точно нужно. Максимум что можно добавить это коды типов ошибок, и то, только если в приложении требуется их по разному обрабатывать (при возврате кода 400 высвечивать разные контролы в зависимости от типа ошибки — неверный телефон или email итп)
Re[5]: Возврат ошибок в API
От: vsb Казахстан  
Дата: 01.07.19 10:08
Оценка:
Здравствуйте, Stalker., Вы писали:

vsb>>Не согласен. Если я забыл задеплоить варку, у меня внезапно куда-то исчезли все юзеры? Не так ведь. Это как я на RSDN зайду, а мне напишут, что тема не существует, вместо того, чтобы написать, что форум перезагружают.


S>не знаю что такое "задеплоить варку"


Скопировать .war архив в нужную папочку.

S>но при "кривой" конфигурации могут легко прийдти и 500-коды, и вообще на практике не требуется клиентам отличать кривую конфигурацию от некривой


Мне требуется. Если сервак не пашет, я хочу юзеру показать, что сервак не пашет, а не "тема удалена или перемещена". 500 коды это хорошо, но приходят 404.

S>зачем куда-то уходить от тела ответа? Оно совершенно точно нужно. Максимум что можно добавить это коды типов ошибок, и то, только если в приложении требуется их по разному обрабатывать (при возврате кода 400 высвечивать разные контролы в зависимости от типа ошибки — неверный телефон или email итп)


Ну как минимум в приложении нужно высветить месседж на нужном языке. Для этого текстовый код и нужен. Если разная обработка нужна, по этим текстовым кодам можно ифы накидать какие надо.

В общем раз парсим текст ответа, значит в коде сообщения никакого смысла нет. Договориться про какой-нибудь 499, чтобы с кодом сервера не пересекаться и всё.
Отредактировано 01.07.2019 10:09 vsb . Предыдущая версия . Еще …
Отредактировано 01.07.2019 10:08 vsb . Предыдущая версия .
Re[6]: Возврат ошибок в API
От: Stalker. Австралия  
Дата: 02.07.19 03:13
Оценка:
Здравствуйте, vsb, Вы писали:

vsb>В общем раз парсим текст ответа, значит в коде сообщения никакого смысла нет. Договориться про какой-нибудь 499, чтобы с кодом сервера не пересекаться и всё.


текст сообщения "парсится" только если внутри ответа 404 надо разные вещи делать в зависимости от внутреннего кода, это будут в основном только формы с данными, где надо подсвечивать разные поля в зависимости от конкретной ошибки бизнес-логики, обычно этого и не надо
Re[9]: Возврат ошибок в API
От: Аноним931 Германия  
Дата: 10.07.19 07:18
Оценка: +1
НС>Речь была не вообще про все коды, а исключительно про 429 vs 500 при перегрузке чего то там внутри сервиса.

И на это выше уже дали абсолютно правильный ответ:

возвратить 4xx клиенту — обвинить клиента в том, что он что-то делает не так. А 5xx — это что-то не так с сервером.
При перегрузке сервера не по вине данного клиента — надо возвращать 503 Service Unavailable.

"Больше 100кмч можно ехать на автобане в любом ряду кроме правого крайнего" (c) pik
"В германии земля в частной собственности" (c) pik
"Закрывать школы, при нулевой смертности среди детей и подростков, это верх глупости" (c) Abalak
Re[2]: Возврат ошибок в API
От: Михаил Романов Удмуртия https://mihailromanov.wordpress.com/
Дата: 04.09.19 12:12
Оценка:
Здравствуйте, RushDevion, Вы писали:

Прошу прощения, что поднимаю старый топик, но давно хотел спросить, а всё как-то было не у кого...
А для чего в практическом плане возвращать разные положительные коды?
RD>200 (OK) — все OK, в теле ответа будут данные
RD>201 (Created) — все ОК, новая сущность создана. Обычно в ответ на POST, в хидере Location — адрес новой сущности. В теле ответа могут быть данные.
RD>202 (Accepted) — все ОК, мы твой запрос приняли, обработаем позже (e.g. положили в очередь). В теле ответа могут быть данные.
RD>204 (No Content) — все ОК, мы твой запрос обработали, но контент вернуть не можем (обычно в ответе на DELETE)

Чем это удобнее, в сравнении с возвращением всегда ровно одного кода, того же 200 и всё?
Т.е. мне представлялось, что какой именно положительный результат мы получим (можем получить) — понятен уже из контекста. Если мы вызывали метод создания — то результатом и должно быть создание, а при удалении контента не будет, и т.д.
Различать может быть полезно в случаях вроде "'вернуть' или 'создать новый и вернуть'", но и то, вроде как не критично нужный случай...

Если не сложно, проясните этот момент.
Re[4]: Возврат ошибок в API
От: GarryIV  
Дата: 04.09.19 13:25
Оценка:
Здравствуйте, vsb, Вы писали:

vsb>Не согласен. Если я забыл задеплоить варку, у меня внезапно куда-то исчезли все юзеры? Не так ведь.


Вот это и надо фиксить если уж на то пошло, 503 вполне подойдет.
WBR, Igor Evgrafov
Re[5]: Возврат ошибок в API
От: vsb Казахстан  
Дата: 04.09.19 14:34
Оценка:
Здравствуйте, GarryIV, Вы писали:

vsb>>Не согласен. Если я забыл задеплоить варку, у меня внезапно куда-то исчезли все юзеры? Не так ведь.


GIV>Вот это и надо фиксить если уж на то пошло, 503 вполне подойдет.


Ну а как ты это пофиксишь, весь серверный софт так работает: апач, нджинкс, томкат. Никогда не видел, чтобы по дефолту кидалось 5xx.
Re[6]: Возврат ошибок в API
От: GarryIV  
Дата: 04.09.19 16:28
Оценка:
Здравствуйте, vsb, Вы писали:

vsb>Ну а как ты это пофиксишь, весь серверный софт так работает: апач, нджинкс, томкат. Никогда не видел, чтобы по дефолту кидалось 5xx.


Например спереди стоит haproxy и форвардит реквесты только если health check урл возвращает ожидаемые данные.
WBR, Igor Evgrafov
Re[3]: Возврат ошибок в API
От: RushDevion Россия  
Дата: 04.09.19 19:13
Оценка: 14 (2)
МР>Если не сложно, проясните этот момент.

Попробую.
Прежде всего, идеологически это соответствует описанию статус-кодов HTTP-протокола.
И там много чисто HTTP-шных нюансов. Например, 200 ответы по-умолчанию кэшируется, а 201/202 — нет.
Кроме того, клиенту никто не мешает просто интерпретировать любой 2xx код как успешный.

С практической же точки зрения, попробую объяснить на примерах:

1. 200 vs 202 (Accepted)
POST /api/payments { id, amount, operationType }
Сервер в зависимости от параметров платежа (сумма, тип) и текущего состояния системы (высокая нагрузка, конкретный провайдер платежа лежит и т.п.) может либо исполнить платеж сразу, либо отложить его на потом.
Поэтому:
200 OK — исполнили сразу, результат вернули, его можно сразу прочитать и отобразить пользователю.
202 Accepted — приняли к исполнению, исполним позже. Клиенту можно не читать body, а сразу идти на GET /api/payments/{id} и проверять статус там.

2. 200 vs 201 (Created)
POST /api/payments { id, amount, operationType }
ID платежа определяет клиент (скажем, это GUID).
А мы со своей стороны гарантируем идемпотентность операции создания, т.е.
мы говорим: "если ты будешь пытаться создать платеж с одним и тем же id много раз, то для нас это нормально".
По HTTP протоколу POST запросы не идемпотентные, но это бывает нужно, если, например у нас слабый канал и клиент реализует какую-то политику ретрая.
Или клиент пропихивает платежи из своей системы в нашу в несколько потоков/процессов.
В этом случае:
201 (Created) — клиент уверен, что это именно он создал платеж. Можно, например, обновлять балансы в своей локальной системе.
200 OK — такой платеж уже есть, но его создали не мы. Просто игнорируем.

Если бы мы возвращали чисто 200, нам бы пришлось как-то менять модель платежа (добавлять какие-то доп. поля/признаки) для обработки такой ситуации, что как-то не очень чисто.

3. 200 vs 204 (No Content)
POST /api/articles/{id} => [ content ]
Допустим мы пишем редактор постов на wiki для такой API-шки (POST соответствует сохранению).
Тогда у нас возможны варианты:
200 OK — твои данные сохранились. Но, похоже, кто-то делал изменения в других частях статьи, и мы их смержили. Прочитай новое тело статьи из тела ответа и обнови UI.
204 OK — твои данные сохранили. Статья на сервере такая же, как локальная, поэтому контента мы тебе не шлем.
Отредактировано 04.09.2019 19:44 RushDevion . Предыдущая версия .
Re[4]: Возврат ошибок в API
От: AK107  
Дата: 05.09.19 17:23
Оценка: +1 -1
Здравствуйте, RushDevion, Вы писали:

RD>2. 200 vs 201 (Created)

RD>POST /api/payments { id, amount, operationType }
RD>ID платежа определяет клиент (скажем, это GUID).
RD>А мы со своей стороны гарантируем идемпотентность операции создания, т.е.
RD>мы говорим: "если ты будешь пытаться создать платеж с одним и тем же id много раз, то для нас это нормально".
RD>По HTTP протоколу POST запросы не идемпотентные, но это бывает нужно, если, например у нас слабый канал и клиент реализует какую-то политику ретрая.
RD>Или клиент пропихивает платежи из своей системы в нашу в несколько потоков/процессов.
RD>В этом случае:
RD>201 (Created) — клиент уверен, что это именно он создал платеж. Можно, например, обновлять балансы в своей локальной системе.
RD>200 OK — такой платеж уже есть, но его создали не мы. Просто игнорируем.

это явный 409 Conflict. и ни в коем случае не 200 ОК.
Re[4]: Возврат ошибок в API
От: Ночной Смотрящий Россия  
Дата: 11.09.19 20:43
Оценка:
Здравствуйте, RushDevion, Вы писали:

RD>201 (Created) — клиент уверен, что это именно он создал платеж. Можно, например, обновлять балансы в своей локальной системе.

RD>200 OK — такой платеж уже есть, но его создали не мы. Просто игнорируем.

Вот это не очень удачная идея. Лучше возвращать 409, а не 200.
... << RSDN@Home 1.3.17 alpha 5 rev. 62>>
Re[5]: Возврат ошибок в API
От: Sinclair Россия https://github.com/evilguest/
Дата: 12.09.19 04:20
Оценка: +1
Здравствуйте, Ночной Смотрящий, Вы писали:

НС>Вот это не очень удачная идея. Лучше возвращать 409, а не 200.

Это если параметры платежа отличаются от того, который записан в системе.
А если совпадают — то 200.
Потому что иначе клиент не может понять, принят ли вообще его платёж, или нет.
В более простом случае: бронируем место в самолёте. Отправляем: "Вася сядет на место 15С".
Если мы получаем 4хх, то мы должны сказать Васе: "извини, не получилось". Конкретно для 409 — "пока мы с тобой тупили, кто-то уже сел на 15С".
Если клиент получил 409 не с первого раза, то он не знает, доходили ли до сервера его предыдущие запросы — т.е. не может отличить ситуацию конликта с самим собой от конфликта с кем-то ещё.
Поэтому если мы получаем такой запрос, а в системе уже записано, что Вася сидит на месте 15С, то мы отдаём 200 — это требование идемпотентности. Мы же не знаем, увидел ли Вася наши предыдущие ответы.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[6]: Возврат ошибок в API
От: KOLRH Финляндия  
Дата: 12.09.19 06:00
Оценка:
Здравствуйте, Sinclair,
S>Поэтому если мы получаем такой запрос, а в системе уже записано, что Вася сидит на месте 15С, то мы отдаём 200 — это требование идемпотентности. Мы же не знаем, увидел ли Вася наши предыдущие ответы.

А может в этом случае стоит возвращать 208 already reported? И не ошибка и известие, что место уже было для вас забронировано.
Re[7]: Возврат ошибок в API
От: Sinclair Россия https://github.com/evilguest/
Дата: 12.09.19 06:35
Оценка:
Здравствуйте, KOLRH, Вы писали:

KOL>Здравствуйте, Sinclair,

S>>Поэтому если мы получаем такой запрос, а в системе уже записано, что Вася сидит на месте 15С, то мы отдаём 200 — это требование идемпотентности. Мы же не знаем, увидел ли Вася наши предыдущие ответы.

KOL>А может в этом случае стоит возвращать 208 already reported? И не ошибка и известие, что место уже было для вас забронировано.

Я бы удивился, получив такой респонс.
Его штатное применение — совсем другой сценарий:

The 208 status never appears as a true HTTP response code in the status line, and only appears in bodies.

https://evertpot.com/http/208-already-reported
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[6]: Возврат ошибок в API
От: Ночной Смотрящий Россия  
Дата: 12.09.19 06:49
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Потому что иначе клиент не может понять, принят ли вообще его платёж, или нет.


Обычно передают некий request id, а не сравнивают поля. И возврат 409 вполне однозначно указывает на то, что запрос с таким id уже обработан.

S>Поэтому если мы получаем такой запрос, а в системе уже записано, что Вася сидит на месте 15С, то мы отдаём 200 — это требование идемпотентности.


POST неидемпотентен по спеке.
... << RSDN@Home 1.3.17 alpha 5 rev. 62>>
Re[7]: Возврат ошибок в API
От: Sinclair Россия https://github.com/evilguest/
Дата: 12.09.19 07:17
Оценка:
Здравствуйте, Ночной Смотрящий, Вы писали:

НС>Обычно передают некий request id, а не сравнивают поля.

Придётся делать и то и то.
НС>И возврат 409 вполне однозначно указывает на то, что запрос с таким id уже обработан.
Нет, так делать нельзя. Что вы будете возвращать в ответ на запрос, который конфликтует с результатом другого запроса с другим id?

S>>Поэтому если мы получаем такой запрос, а в системе уже записано, что Вася сидит на месте 15С, то мы отдаём 200 — это требование идемпотентности.

НС>POST неидемпотентен по спеке.
Поэтому надо делать PUT.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[8]: Возврат ошибок в API
От: Ночной Смотрящий Россия  
Дата: 12.09.19 07:28
Оценка:
Здравствуйте, Sinclair, Вы писали:

НС>>Обычно передают некий request id, а не сравнивают поля.

S>Придётся делать и то и то.

Зачем?

НС>>И возврат 409 вполне однозначно указывает на то, что запрос с таким id уже обработан.

S>Нет, так делать нельзя. Что вы будете возвращать в ответ на запрос, который конфликтует с результатом другого запроса с другим id?

400. Либо можно возвращать конкретную причину в теле 409. Главное — вся эта котовасия должна отрабатываться на уровне мидлвера и retry policy, а не лезть в BL.

S>>>Поэтому если мы получаем такой запрос, а в системе уже записано, что Вася сидит на месте 15С, то мы отдаём 200 — это требование идемпотентности.

НС>>POST неидемпотентен по спеке.
S>Поэтому надо делать PUT.

Про PUT совсем другой разговор, там свои заморочки. И вот там то как раз нужно полное сравнение всех полей.
... << RSDN@Home 1.3.17 alpha 5 rev. 62>>
Re[7]: Возврат ошибок в API
От: Sharov Россия  
Дата: 12.09.19 09:48
Оценка:
Здравствуйте, Ночной Смотрящий, Вы писали:

НС>POST неидемпотентен по спеке.


Но имплементация в конкретном сервисе может быть идемпотентной?
Кодом людям нужно помогать!
Re[8]: Возврат ошибок в API
От: Ночной Смотрящий Россия  
Дата: 12.09.19 11:26
Оценка:
Здравствуйте, Sharov, Вы писали:

S>Но имплементация в конкретном сервисе может быть идемпотентной?


Может. Но 409 при повторном вызове отсутствия идемпотентности не означает.
... << RSDN@Home 1.3.17 alpha 5 rev. 62>>
Re[4]: Возврат ошибок в API
От: VladiCh  
Дата: 13.09.19 23:48
Оценка:
Здравствуйте, MadHuman, Вы писали:

MH>Здравствуйте, Ночной Смотрящий, Вы писали:


MH>>>если сервера — 500 (это перегрузка сервера

НС>>Для перегрузки есть специальный код, 429.
MH>да, но 429 (Too Many Requests) — для более узкого случая, когда хотят на сервере ограничить частоту реквестов от клиента. в этом случае да, лучше его.
MH>я имел ввиду несколько другие ситуации, например для обработки реквеста надо сходить в базу, база перегружена и ответила соотвествующей ошибкой.
MH>или сервер под высокой нагрузкой и реквест клиента по каким-то причинам (особенно связанным с данными клиентам) выполняется слишком долго и его прервали.
MH>или сервер уже под высокой нагрузкой и пока лучше не начинать обработку новых запросов.
MH>типа такого.

Для других случаев обычно используется 503
Re: Возврат ошибок в API
От: white_znake  
Дата: 24.10.19 10:50
Оценка:
Здравствуйте, Буравчик, Вы писали:

Б>Какие HTTP status code используются в ваших API?

Б>200, 401, 403, 404 и т.п.
Добавил бы 201 — Created со ссылкой на созданный ресурс в заголовке Location. 201-created полезен на случай когда клиент что-то создает и нужен переход на созданный ресурс (мало-ли пользователь захочет еще что-то отредактировать).
И 204 — No Content. Все ок, но контента нет. Полезен для ответов на Delete, на пример.

Иногда приходилось использовать 409 — Confilct для того, что бы показать, что модифицированные пользователем данные были изменены ранее.

Б>Передаете ли дополнительную информацию об ошибках? Какую?

Б>Код ошибки, текстовое сообщение, на каком языке (русский, английский), дополнительные параметры?
json: {code: <литеральный код ошибки>, message: <сообщение для разработчиков>, description: <пояснение ошибки и что надо сделать, что бы ее не получить для разработчиков>}.
Разработчики клиентской части уже обрабатывают коды ошибок. Текс ошибок и пояснение им нужны в отладке Rest API через swagger. Тестировщикам для локализации багов тоже будет полезно получать текст ошибок и описание.

Б>Кодируете ошибки, как? Единая нумерация для всего API, или свои ошибки для каждого endpoint?

Просто литералы. Который указываешь в описании API.

Б>Используете какие-то правила для возвратов ошибок?

Б>Например, по аналогии с JSON-RPC, в котором наличие в ответе поля errors означает, что произошла ошибка при обработке запроса.
На клиенте? Проверяешь http.status

Б>Что возвращаете, если клиент запрашивает существующий ресурс, к которому запрещен доступ:

Б>404 или 403?
Лучше все-таки различать 403 — Forbidden & 404 — Not Found. Будет меньше вопросов у клиентов.
Возможно, что в некоторых случай помимо 404, можно вернуть 410 — Gone. Если на клиенте кешируются ресурсы и идет запрос на обновление этого ресурса, которого уже нет на сервере, то имеет смысл вернуть 410, хотя, если вернуть 404 — это тоже небольшая проблема. Просто 404 говорит о том, что ресурс не найден, но возможно потом он будет доступен. А вот если ресурс был, но теперь ушел и больше не вернется, то 410.

Б>В общем, научите как надо возвращать информацию об ошибках в API


https://developer.mozilla.org/ru/docs/Web/HTTP?
Re[2]: Возврат ошибок в API
От: white_znake  
Дата: 24.10.19 10:58
Оценка:
Здравствуйте, Ночной Смотрящий, Вы писали:

НС>Уникальный код, severity, источник, нелокализуемое сообщение на английском, название параметра если применимо, значения подстановок для локализованного сообщения. В отладочных версиях еще stacktrace.

На мой взгляд, лучше делать так, что бы StackTrace ни когда не покидал бы сервер
Тогда не возникнет гипотетическая ошибка, по которой и на проде, stacktrace уйдет клиенту
Нормальный вариант логировать stacktrace, логи смотреть через http с авторизацией.
Re[3]: Возврат ошибок в API
От: Ночной Смотрящий Россия  
Дата: 24.10.19 11:02
Оценка:
Здравствуйте, white_znake, Вы писали:

_>На мой взгляд, лучше делать так, что бы StackTrace ни когда не покидал бы сервер

_>Тогда не возникнет гипотетическая ошибка, по которой и на проде, stacktrace уйдет клиенту

Если это в одном месте настраивается, то не возникнет.

_>Нормальный вариант логировать stacktrace, логи смотреть через http с авторизацией.


Логи обычно доступны только владельцам сервиса, а вот стектрейс часто полезен тем, кто использует отладочные версии.
... << RSDN@Home 1.3.17 alpha 5 rev. 62>>
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.