Яка відповідна відповідь коду статусу HTTP для загального невдалого запиту (не помилки)?


109

Я створюю RESTful API, який буде обробляти ряд взаємодій користувачів, включаючи розміщення замовлень за допомогою збережених кредитних карток.

У разі успішного замовлення я повертаю 200 ОК, а у випадку, коли запит замовлення неправильний або недійсний, я повертаю 400 Поганий запит. Але що я повинен повернути, якщо виникає проблема під час фактичної обробки замовлення?

  1. Клієнтське замовлення POSTS на сервер для користувацького ресурсу. Якщо користувача не існує, повертається 404 Not Found.
  2. Формат замовлення та інформація підтверджена. Якщо недійсна, повертається 400 поганих запитів.
  3. Замовлення обробляється. Якщо замовлення успішно, для замовлення повертається 201 Created. Якщо трапляється несподівана помилка, повертається помилка 500 сервера.

Останній крок - проблема - що я повертаю, якщо замовлення не завершиться з будь-якої іншої причини? Можливі сценарії можуть включати:

  • Товар розпроданий
  • Досягнуто максимальний ліміт замовлень користувача
  • Помилка трансакції кредитної картки (недостатня кількість коштів тощо)

Це не здається, що було б доречним або для 400, або для 500. Якщо що-небудь, я міг би розглянути його як 400, якщо немає кращого коду - запит був недійсним згідно з діловими правилами. Це не здається точним.

Редагувати: Також знайшлося це обговорення цієї теми. Всі відповіді там, схоже, вказують на використання кодів статусу для цього типу порушень, з деякою дискусією між використанням 400, 409 або розширення 422.


8
Мені подобається "422 не оброблюваний об'єкт" за помилки перевірки. І використовуйте його для ваших вище прикладів, включіть у відповідь повідомлення з актуальною бізнес-проблемою "Товар розпродано" і, можливо, додайте власні "коди", якщо клієнту необхідно програмно приймати різні рішення на основі відповіді
house9

перш ніж перейти до 422, подумайте, чи підтримуєте ви можливості WebDAV
Mbithy Mbithy

Відповіді:


90

Ви повинні використовувати 400 для правил бізнесу. Не повертайте 2xx, якщо замовлення не було прийнято. HTTP - це протокол програми, ніколи цього не забувайте. Якщо ви повернетесь 2xx, клієнт може вважати, що замовлення було прийнято, незалежно від будь-якої інформації, яку ви надсилаєте в тілі.


З кулінарної книги RESTful Web Services :

Однією поширеною помилкою, яку роблять деякі веб-служби, є повернення коду статусу, який відображає успіх (коди статусу від 200 до 206 та від 300 до 307), але включає тіло повідомлення, яке описує стан помилки. Це не дозволяє HTTP-програмі виявляти помилки. Наприклад, кеш буде зберігати його як успішну відповідь та подавати його наступним клієнтам, навіть коли клієнти можуть зробити успішний запит.

Я залишаю це для вас, щоб вибрати між 4xx та 5xx, але ви повинні використовувати код статусу помилки.


1
Чи є у вас приклади чи посилання на цей підхід порівняно з іншими? І Ваші відповіді, і відповіді Відора мають сенс: одна з точки зору HTTP як протоколу програми, а інша, оскільки вона суворо спрямована на мету передачі. Специфікація визначає це як "протокол на рівні програми", що трохи розпливчасто. Я також бачив і перспективи, і приклади в Інтернеті, коли досліджував це.
Raelshark

це так правда.
Юний Хюн Ю

2
Ви маєте на увазі: "Ви повинні використовувати 4xx для правил бізнесу"?
Явар

28

Ви повинні використовувати 4xx для помилки клієнта, якщо клієнт може змінити запит, щоб уникнути помилки. Використовуйте 5xx для помилки на сервері, яку клієнт не може реально обійти.

Продукт, який продається, буде помилкою сервера. Клієнт не може змінити запит якось, щоб уникнути помилки. Ви можете перейти на інший товар, але чи не це буде новий запит?

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

Помилка операції з кредитною карткою буде помилкою клієнта. Клієнт може повторно подати запит за допомогою іншого способу оплати чи номера кредитної картки, щоб усунути помилку.


6
Якщо ліміт замовлення досягнуто, чи не повинен клієнт сповіщати про це користувача та дозволити йому відповідним чином змінити запит? Це здається помилкою 4xx. Те саме стосується товару, який продається. Помилки 5xx призначені для помилок, викликаних тим, що система певним чином виходить з ладу, а не для дії, забороненої бізнес-правилом.
carlin.scott

7
Я згоден з коментарем вище. Помилки 5xx - це коли проблеми з сервером. 4xx помилки для бізнес-правил.
Merc

21

Тип помилки:

4×× Client Error

Код помилки:

422 Unprocessable Entity

Сервер розуміє тип вмісту об’єкта запиту (отже, код статусу 415 непідтримуваного типу мультимедіа є невідповідним), і синтаксис об'єкта запиту є правильним (таким чином, код статусу 400 Bad Bad Request недоречний), але не зміг обробити вміст інструкції.

Наприклад, ця умова помилки може виникнути, якщо тіло запиту XML містить добре сформовані (тобто синтаксично правильні), але семантично помилкові інструкції XML.

https://httpstatuses.com/422


16

Я знаю, що це питання давнє, але я придумав саме таке питання сьогодні. Якщо у мого користувача не вистачає кредитів, який код статусу повинен повернути мій REST API?

Я схиляюся до 402 Payment Required:

За даними Вікіпедії :

Зарезервовано для подальшого використання. Первісний намір полягав у тому, що цей код може використовуватися як частина якоїсь цифрової схеми готівкових коштів або мікроплатежів, але цього не сталося, і цей код зазвичай не використовується. API для розробників Google використовує цей статус, якщо конкретний розробник перевищив щоденний ліміт запитів.

І справді вони :

PAYMENT_REQUIRED (402)

  • Досягнуто щоденного обмеження бюджету, встановленого розробником.
  • Запрошена операція вимагає більше ресурсів, ніж дозволяє квота. Оплата необхідна для завершення операції.
  • Запрошена операція вимагає певної оплати від автентифікованого користувача.

Це найбільш продумана і логічна відповідь.
GTodorov

5

Як щодо 424 Failed Dependency? Специфікація описує це як:

Метод не вдалося виконати на ресурсі, оскільки запитувана дія залежала від іншої дії, і ця дія не вдалася.

Але є і таке визначення :

Код статусу 424 визначений у стандарті WebDAV і стосується випадку, коли клієнту потрібно змінити те, що він робить - сервер тут не відчуває жодних проблем.

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

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


Іншим варіантом може бути 422 Unprocessable Entity:

Сервер розуміє тип вмісту об’єкта запиту (отже, код статусу 415 непідтримуваного типу мультимедіа є невідповідним), і синтаксис об'єкта запиту є правильним (таким чином, код статусу 400 Bad Bad Request недоречний), але не зміг обробити вміст інструкції.

Наприклад, ця умова помилки може виникнути, якщо тіло запиту XML містить добре сформовані (тобто синтаксично правильні), але семантично помилкові інструкції XML.

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

MozDev каже, що це вказує на помилку на стороні клієнта, зокрема: Клієнт не повинен повторювати цей запит без змін.

Loopback 4 використовує 422, коли перевірка введення не вдається.


Можливо, недостатні ночі на складі або на складі можуть вважатися тимчасовими станами, тому запит можна буде повторити повторно пізніше. На цю ситуацію можна вказати503 Service Unavailable

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

Сервер МОЖЕ надсилати поле заголовка "Повторити повтор", щоб запропонувати клієнту відповідну кількість часу, перш ніж повторити запит.


Жоден із них не стосується платежу. Я йду з 402 з попередньої відповіді!
Гтодоров

2

Я не думаю, що 400 можна використовувати для всього сценарію бізнесу. Його можна використовувати для перевірки базових даних. Крім того, нам може бути важко вписати іншу ділову логіку в цей код помилки. Помилка, якою обробляється ця проблема, - це переважно помилки в часі розробки, з якими розробник може зіткнутися можливо під час кодування клієнта.

Скажімо, всі параметри правильні, і скажімо, що ми передаємо номер запиту користувача у запит.

Тому запит тепер не є поганим запитом, сервер може прийняти запит. Але зараз він відмовляється від заповнення запиту на основі нової доступної інформації, яка є - рахунок не має достатнього балансу.

Я б запропонував використовувати в цих сценаріях 403 з відповідним повідомленням про помилку.

Інший можливий код помилки може бути конфліктом 409. Але це використовується в сценаріях, коли ресурс знаходиться в постійному стані.


-1

Я йду з 406 Not Acceptable.

Ось список 4xx:

const HTTP_BAD_REQUEST = 400;
const HTTP_UNAUTHORIZED = 401;
const HTTP_PAYMENT_REQUIRED = 402;
const HTTP_FORBIDDEN = 403;
const HTTP_NOT_FOUND = 404;
const HTTP_METHOD_NOT_ALLOWED = 405;
const HTTP_NOT_ACCEPTABLE = 406;
const HTTP_PROXY_AUTHENTICATION_REQUIRED = 407;
const HTTP_REQUEST_TIMEOUT = 408;
const HTTP_CONFLICT = 409;
const HTTP_GONE = 410;
const HTTP_LENGTH_REQUIRED = 411;
const HTTP_PRECONDITION_FAILED = 412;
const HTTP_REQUEST_ENTITY_TOO_LARGE = 413;
const HTTP_REQUEST_URI_TOO_LONG = 414;
const HTTP_UNSUPPORTED_MEDIA_TYPE = 415;
const HTTP_REQUESTED_RANGE_NOT_SATISFIABLE = 416;
const HTTP_EXPECTATION_FAILED = 417;
const HTTP_I_AM_A_TEAPOT = 418;                                               // RFC2324
const HTTP_MISDIRECTED_REQUEST = 421;                                         // RFC7540
const HTTP_UNPROCESSABLE_ENTITY = 422;                                        // RFC4918
const HTTP_LOCKED = 423;                                                      // RFC4918
const HTTP_FAILED_DEPENDENCY = 424;                                           // RFC4918
const HTTP_RESERVED_FOR_WEBDAV_ADVANCED_COLLECTIONS_EXPIRED_PROPOSAL = 425;   // RFC2817
const HTTP_UPGRADE_REQUIRED = 426;                                            // RFC2817
const HTTP_PRECONDITION_REQUIRED = 428;                                       // RFC6585
const HTTP_TOO_MANY_REQUESTS = 429;                                           // RFC6585

8
Хоча ім'я коду статусу 406 може звучати саме по собі, вам потрібно знати, що кожен код статусу має авторитетний текстовий опис. Опис коду статусу 406 не підходить для конкретного випадку. Наприклад , див. Httpstatuses.com/406 .
Zero3

1
@ Zero3 правильно, цей код означає, що тип відповіді неприйнятний, оскільки існує невідповідність між заголовками Accept, надісланими від клієнта, та MediaType (іми), що надсилаються кінцевою точкою, наприклад, application / json vs. text / plain
Gregor
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.