Чи слід використовувати коди статусу HTTP для представлення помилок ділової логіки на сервері?


20

Я перебуваю на перехресті з деяким дизайном API для клієнта (JS у браузері), щоб поговорити з сервером. Ми використовуємо HTTP 409 Conflict для представлення невдалої дії через дію запобіжного блокування. Замок satefy запобігає випадковим внесенням змін у виробничі системи наших клієнтів. Мені було доручено попрацювати з 409s трохи більш витончено клієнтом, щоб вказати, чому конкретний виклик API не вдався.

Моє рішення полягало в тому, щоб перекрити обробники відмов будь-якого з наших дзвінків AJAX, які відображатимуть сповіщення про клієнта, коли щось виходить з ладу через 409 - це все нормально і добре працює поряд з іншими помилками 4XX і 5XX, які використовують той самий механізм.

Виникла проблема, коли один із наших обробників маршрутів відповідав на 409s, коли виникає помилка ділової логіки - моя обгортка AJAX повідомляє, що запобіжник увімкнено, тоді як існуючий обробник несправності клієнта повідомляє, що (на його думку) проблема базується на тілі відповіді. Простим рішенням було б змінити відповідь обробника або код статусу, який ми використовуємо для представлення блокування безпеки.

Що приводить мене до мого перехрестя: чи повинні коди статусу HTTP навіть використовуватися для представлення помилок ділової логіки? Це питання стосується тієї ж проблеми, з якою я стикаюся, але вона не отримала особливої ​​тяги. Як запропоновано у пов'язаній відповіді, я схиляюся до використання HTTP 200 OK з відповідним органом, щоб представити збій у діловій логіці.

У когось є якісь переконання? Хтось може переконати мене, що це неправильний спосіб представити невдачу?


3
Я вагаюся, коли висловлюю свою просту думку як відповідь. Якщо коротко: я зазвичай уникаю використання кодів HTTP-статусу для представлення бізнес-помилок. Вони повинні стосуватися лише стану зв'язку між клієнтом та сервером. Підходящий код стану для повернення помилок перевірки чи логіки бізнесу 400 Bad Request. Причина такого розмежування полягає в тому, що майбутні системи, розробники чи читачі документів можуть бути заплутані вашим відхиленням від світового стандарту.
Іво Куманс

@IvoCoumans: будь ласка, зробіть це ^ відповіддю, щоб я міг його схвалити. 400 Bad Requestяк ковдра HTTP-код, здається, найкраще покриває помилки ділової логіки як клас.
9000

Особисті переваги, але я схильний використовувати, 400 Bad Requestколи дані відсутні або неможливо прочитати / проаналізувати. Тобто самі дані запиту в чомусь погані.
Спікер Кейсі

Будь ласка, розкрийте, що ви маєте на увазі під "помилкою бізнес-логіки". Це надзвичайно розпливчасто. Ви маєте на увазі недійсне введення даних (правильних) перевірок перевірки даних, введення, яке може бути дійсним в інший момент часу, але недійсне в поточному стані, або помилка в бізнес-логіці, коли він відхиляє дійсний ввід?
jpmc26

@ jpmc26 Я навмисно розпливався, оскільки це було загальним питанням. Сервери впоралися із запитом чудово, але вирішили, що запит / твердження не має сенсу.
Джо Шанахан

Відповіді:


19

Кейсі висвітлює основну точку.

Ключова ідея будь-якої веб-програми: ви адаптуєте свій домен так, щоб він виглядав як магазин документів. GET / PUT / POST / DELETE тощо - це всі способи взаємодії зі сховищем документів.

Так в способі мислення про те , що коди використання, щоб зрозуміти , що аналогічна операція в документі магазині, і що ця невдача буде виглядати в цьому аналогу.

2xx абсолютно непридатний

2xx (Успішний) клас коду статусу вказує на те, що запит клієнта був успішно отриманий, зрозумілий та прийнятий.

5xx також непридатний

Клас коду статусу 5xx (помилка сервера) вказує на те, що сервер знає, що він помилився

У цьому випадку сервер не помилився; відомо про те, що наразі вам не слід змінювати цей ресурс.

Помилки бізнес-логіки (мається на увазі, що інваріант бізнесу не дозволяє запропонувати редагувати наразі), ймовірно, 409

Код стану 409 (конфлікт) вказує, що запит не міг бути виконаний через конфлікт із поточним станом цільового ресурсу. Цей код використовується в тих ситуаціях, коли користувач, можливо, зможе вирішити конфлікт і повторно подати запит. Сервер ДОЛЖЕН генерувати корисну навантаження, яка включає достатню кількість інформації для користувача, щоб розпізнати джерело конфлікту.

Зверніть увагу на цей останній шматочок - корисне навантаження відповіді 409 повинно повідомляти споживачеві інформацію про те, що пішло не так, і в ідеалі включає в себе контроль гіпермедіа, який приводить споживача до ресурсів, які можуть допомогти вирішити конфлікт.

Моє рішення полягало в тому, щоб перекрити обробники відмов будь-якого з наших дзвінків AJAX, які відображатимуть сповіщення про клієнта, коли щось виходить з ладу через 409 - це все нормально і добре працює поряд з іншими помилками 4XX і 5XX, які використовують той самий механізм.

І я зазначив би це як проблему; Ваша реалізація у клієнта припускала, що код статусу є достатнім для визначення проблеми. Натомість ваш клієнтський код повинен переглядати корисне навантаження та діяти на наявній там інформації.

Тобто, зрештою, як це зробив би магазин документів

409  Conflict

your proposed change has been declined because ${REASON}.  
The following resolution protocols are available: ${LINKS[@]})

Той самий підхід з a 400 Bad Requestтакож був би прийнятний; що приблизно "перекладається на" Виникла проблема з вашим запитом. Нам не шкода зрозуміти, який код статусу найкраще підходить, тож ось вам. Детальні відомості див. У корисному навантаженні ".

Я б використовував 422. Введення дійсне, тому 400 не є правильним кодом помилки для використання

Специфікація WebDAV включає цю рекомендацію

Код стану 422 (Unprocessable Entity) означає, що сервер розуміє тип вмісту об'єкта запиту (отже, код статусу 415 (непідтримуваний тип медіа) неприйнятний), і синтаксис об'єкта запиту є правильним (таким чином, 400 (поганий запит) (код статусу невідповідний), але не вдалося обробити містяться інструкцій. Наприклад, ця умова помилки може виникнути, якщо орган запиту XML містить добре сформовані (тобто синтаксично правильні), але семантично помилкові інструкції XML.

Я не вірю, що це цілком збіг (хоча я згоден, що це викликає певні сумніви 400як альтернативу). Моя інтерпретація полягає в тому, що 422означає "ви надіслали неправильну сутність", де 409"ви надіслали організацію в неправильний час".

По-іншому, 422вказує на проблему з повідомленням запиту, розглянутим ізольовано, де 409вказується, що повідомлення запиту суперечить поточному стану ресурсу.

Дискусія Бен Надала про 422 може бути корисною для розгляду.


5
" ви адаптуєте свій домен так, щоб він виглядав як сховище документів " - я хотів би бачити, як люди читають це, і повністю розуміють усі наслідки та наслідки, перш ніж вони вирішать (або проти) REST. Дійсно.
JensG

"Помилки бізнес-логіки" для мене звучать як "недійсний ввід", який, як правило, є прямим 400, оскільки для нього немає більш конкретного коду помилки. Якщо не вхід недійсний, то сервер має помилку і 500 є відповідним. Здається, ваша відповідь передбачає занадто багато природи "помилки ділової логіки".
jpmc26

Я б використовував 422. Введення дійсне, тому 400 не є правильним кодом помилки для використання
Конрад

19

На мій досвід, коди помилок HTTP недостатньо для представлення бізнес-помилок. Однак вони корисні для представлення класів помилок.

Отже, моя рекомендація полягатиме в тому, щоб використовувати коди помилок HTTP для категорій помилок, але вибирати конкретну помилку для відмов ділової логіки (наприклад, 409 Конфлікт ... 200 ОК буде вводити в оману) і включати дані у відповідь із зазначенням конкретної бізнес-помилки . Переконайтеся, що це частина вмісту відповіді, а не текст статусу, оскільки деякі веб-переглядачі ігнорують спеціальний текст статусу. Мова, яку я люблю використовувати, має типи Union, які зручні для представлення повідомлень. Але ви також можете визначити рядкові константи для випадків помилок.

Приклади

// error with text response
409 Conflict "safety_lock_engaged"
409 Conflict "customer_not_eligible_for_selected_discount"
// warning with JSON response
202 Accepted { "backorderedProductIds": [ 37, 476 ] }

Коди статусу 4xx вище 400 мають дуже специфічні значення. Виберіть 400, якщо ваш випадок спеціально не охоплюється іншими.
jpmc26

@ jpmc26 Якщо я не використовую коди статусу таким чином, вони ніколи не використовуються. Але сміливо використовуйте їх правильно і правильно у своїх відповідях.
Спікер Кейсі

У деякому сенсі ти маєш рацію. Вони ніколи не використовуються. Значення, вибрані для конкретних кодів, схоже, не є дуже поширеними випадками використання для більшості програм. Нічого страшного. Існує маса винятків, які ми ніколи не пишемо, щоб їх наздогнати.
jpmc26


Не кидання або ловлення для конкретних типів винятків є аналогом того, що ніколи не використовувати конкретні коди HTTP або будь-які інші коди помилок. Я припускав, що це буде очевидно. Чи є модель винятку "найкращою", абсолютно не має значення.
jpmc26

5

Як правило, я б уникав використання кодів HTTP-статусу для представлення конкретних помилок ділової логіки. Це тому, що вони вже мають смислове значення, яке визначається світовим стандартом. Інші системи, нові диски та інше будуть заплутані вашим відхиленням від стандарту.

Я знайшов у останніх подібних дослідженнях те, що його прийнято використовувати 400 Bad Requestу випадку помилок перевірки і подібних. Таким чином, ви використовуєте один код статусу для всіх помилок бізнес-логіки.

Між іншим, його 409слід використовувати, коли ресурс змінився під час редагування та спробу зберегти його знову.


4

Ви можете скористатися "Поганим запитом" та включити ідентифікатор порушеного бізнес-правила плюс додаткові деталі на тілі відповіді.


Я не знаю, за що це було проголосовано. Ось як компанії можуть повертати винятки з бізнесу.
Скадоош
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.