Помилка REST API повертає добрі практики [закрито]


623

Я шукаю вказівки щодо передового досвіду щодо повернення помилок з REST API. Я працюю над новим API, тому зараз я можу взяти його в будь-якому напрямку. На даний момент моїм типом вмісту є XML, але я планую підтримувати JSON у майбутньому.

Зараз я додаю деякі випадки помилок, наприклад, наприклад, клієнт намагається додати новий ресурс, але перевищив його квоту на зберігання. Я вже обробляю певні випадки помилок з кодами статусу HTTP (401 для аутентифікації, 403 для авторизації та 404 для URI-адрес простого неправильного запиту). Я переглянув блаженні коди помилок HTTP, але жоден із діапазонів 400-417 не здається правильним повідомляти про додаткові помилки. Тож спочатку я спокусився повернути свою помилку програми з 200 ОК та конкретним корисним навантаженням XML (тобто. Платіть нам більше, і ви отримаєте потрібне вам сховище!), Але я перестав думати про це, і, здається, мильний (/ від жаху знизати плечима). Крім того, я відчуваю, що я розбиваю відповіді на помилки на окремі випадки, оскільки деякі керуються кодом статусу http, а інші керуються вмістом.

То що таке галузеві рекомендації? Належні практики (будь-ласка, поясніть, чому!), А також, від клієнта pov, який вид обробки помилок в API REST полегшує життя коду клієнта?


7
Просто для уточнення: мене не стільки цікавить, який саме код статусу HTTP повернути, а чи хороша практика REST поєднувати помилки корисного навантаження з кодами статусу HTTP чи краще покладатися виключно на корисну навантаження.
Рем Русану

3
Посібник з дизайну REST API досить добре висвітлює цю тему.
Рем Русану

12
Питання не запитує думки, а вказує на рекомендації та має бути повторно відкритим і використовуватись як орієнтир. Що було
сенсом

4
Більшість не згадували, але використання кодів помилок HTTP може призвести до проблем щодо основної причини проблеми. HTTP - транспортний протокол, і 404 повинен вказувати на те, що виникла проблема з транспортним рівнем URLon (наприклад, неправильний шлях). Якщо програма не може знайти набір даних за своїм ідентифікатором, це помилка рівня програми (не помилка рівня транспорту) і 404, як пропонують спокійні користувачі коду статусу http, може призвести до неправильного висновку. Як правило, мені не подобається поєднання транспортного та додаткового шару при використанні кодів статусу.
SCI

Відповіді:


220

Тож спочатку я спокусився повернути свою помилку програми з 200 ОК та конкретним корисним навантаженням XML (тобто. Платіть нам більше, і ви отримаєте потрібне вам сховище!), Але я перестав думати про це, і, здається, мильний (/ від жаху знизати плечима).

Я б не повернув 200, якщо справді не було нічого поганого в запиті. З RFC2616 , 200 означає "запит вдався".

Якщо квота на зберігання клієнта була перевищена (з будь-якої причини), я поверну 403 (Заборонено):

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

Це повідомляє клієнту, що з запитом було нормально, але він не вдався (щось 200 не робить). Це також дає можливість пояснити проблему (та її вирішення) в органі відповіді.

Які ще конкретні умови помилки ви мали на увазі?


6
Чи повинен я включити своє детальне повідомлення про помилку в тілі, тобто пара коду XML / рядок? Як клієнти найкраще справляються з цим? Наприклад, я знаю, що клієнти, що базуються на C # WebRequest, будуть кидати "Поганий запит" або "Заборонено" і не даватимуть органу відповіді.
Рем Русану

18
Тіло 403 "повинне" містити деталі помилки. Чи готовий клієнт використати інформацію - це вже інша історія. Найбільш сенс для цього формату бути таким же, як і формат для всіх інших корисних навантажень (наприклад, XML, JSON).
Багатий Аподака

1
... і якщо деталі не повернуті в 403, замість цього можна використовувати 404 "можна" (не здається мені найкращим варіантом).
Багатий Аподака

6
Варіант 404 передбачає те, що 403 може розкрити деталі про програму, про яку ви не хочете, щоб несанкціоновані користувачі знали - якщо, наприклад, користувач, що не адміністратор, потрапляє на URL-адресу, призначену лише для адміністратора, ви можете не бажати цього користувача знати, що це дійсна URL-адреса для адміністраторів тощо. Однак у цьому випадку 403 цілком підходить.
Грег Кемпбелл

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

584

Чудовий ресурс для вибору правильного коду помилки HTTP для вашого API: http://www.codetinkerer.com/2015/12/04/choosing-an-http-status-code.html

Уривок із статті:

З чого почати:

введіть тут опис зображення

2XX / 3XX:

введіть тут опис зображення

4XX:

введіть тут опис зображення

5XX:

введіть тут опис зображення


1
422 - це розширення WebDAV. Я думаю, що тут не повинно бути.
Маріо

@Mario Ідіоматично в API Ruby on Rails повертати 422 у відповідь на умови, зазначені тут. Багато корисного за цим підходом вже є. На що б ви замінили використання 422?
Келсі Ханнан

регулярні старі 400
Andbdrew

Дякую. Що означає "Чи ви кидаєте злобу в Інтернеті?"
RoutesMaps.com


87

Основним вибором є те, чи хочете ви розглядати код статусу HTTP як частину свого REST API чи ні.

Обидва способи працюють добре. Я погоджуюся, що, строго кажучи, одна з ідей REST полягає в тому, що ви повинні використовувати код статусу HTTP як частину свого API (поверніть 200 або 201 для успішної операції та 4xx або 5xx залежно від різних випадків помилок.) Однак , поліції REST немає. Ви можете робити те, що хочете. Я бачив набагато більш кричущі API, які не є REST, називаються "RESTful".

На даний момент (серпень, 2015 р.) Я рекомендую використовувати код статусу HTTP як частина свого API. Зараз набагато простіше бачити зворотний код при використанні фреймворків, ніж це було раніше. Зокрема, зараз простіше бачити випадок повернення без 200 та сукупність не 200 відповідей, ніж це було раніше.

Код статусу HTTP є частиною вашої програми

  1. Вам потрібно буде ретельно підбирати 4xx-коди, які відповідають вашим умовам помилок. Ви можете включити повідомлення про відпочинок, xml або в простому тексті як корисне навантаження, що включає під-код та описовий коментар.

  2. Клієнтам потрібно буде використовувати програмне забезпечення, яке дозволяє отримувати код статусу на рівні HTTP. Зазвичай зробити це можливо, не завжди прямо.

  3. Клієнтам доведеться розрізняти коди статусу HTTP, які вказують на помилку зв'язку, та ваші власні коди статусу, які вказують на проблему на рівні програми.

Код статусу HTTP НЕ є частиною вашої програми

  1. Код статусу HTTP завжди буде 200, якщо ваша програма отримала запит, а потім відповіла (як випадки успіху, так і помилки)

  2. ВСІ ваші відповіді повинні містити інформацію про «конверт» або «заголовок». Зазвичай щось на зразок:

    envelope_ver: 1.0
    статус: # використовувати будь-які коди, які вам подобаються. Зарезервуйте код для успіху.
    msg: "ok" # рядок людини, що відображає код. Корисно для налагодження.
    data: ... # Дані відповіді, якщо такі є.
  3. Цей спосіб може бути простішим для клієнтів, оскільки статус для відповіді завжди знаходиться в одному і тому ж місці (не потрібні підкоди), немає обмежень на коди, не потрібно отримувати код статусу на рівні HTTP.

Ось публікація з подібною ідеєю: http://yuiblog.com/blog/2008/10/15/datatable-260-part-one/

Основні питання:

  1. Обов’язково введіть номери версій, щоб ви могли пізніше змінити семантику api за потреби.

  2. Документ ...


8
Тай. Варіант 2 здається
милом

138
Ні, тунелювання всього через 200 взагалі не заспокоює. Це заважає посередникам розуміти результат операції, що знищить будь-яку форму кешування, приховає семантику операції і накладає розуміння змісту повідомлення для обробки помилки, порушуючи обмеження автономних повідомлень.
SerialSeb

13
Повернення деталей помилки з 200 може не бути RESTful, але це все-таки корисна відповідь (якщо ви ігноруєте зауваження "Обидва способи спокійні") ... Більш важливим моментом може бути те, що API RESTful може бути не найкращим варіантом для ОП.
МБ.

3
Здається, існує загальне розуміння того, що ви можете робити все, що завгодно, за допомогою протоколу HTTP і все ще бути "RESTy", це неправда. Використовуйте протокол для написаного, це одна з основних ідей REST. Отже код статусу повинен бути частиною вашого протоколу.
Аріель М.

Суть кодів статусу полягає у наданні спільної мови розуміння між різними мовами програмування, рамками та підходами. Значення коду статусу близькі до універсальних: ваш власний орган - який по суті додає більшої складності за допомогою спеціального синтаксису, який повинні засвоїти ваші споживачі API - це не так.
Келсі Ханнан

40

Пам'ятайте, що існує більше кодів статусу, ніж визначених у RFC HTTP / 1.1, реєстр IANA знаходиться за адресою http://www.iana.org/assignments/http-status-codes . У випадку, коли ви згадали код статусу 507, звучить правильно.


3
Хм, хоча, на перший погляд, "507 недостатнього обсягу зберігання" здається, що це може бути доречним, я б з нетерпінням використовував його, оскільки він призначений як (досить специфічне) розширення WebDAV, а не загальне "ей, у вас немає місця" виняток. Все-таки, я гадаю, ви могли б ним скористатися.
Макс

1
Ні, це зовсім не WebDAV. Існує причина, чому існує реєстр кодів статусу HTTP.
Джуліян Решке

25
Я не згоден з 507цією метою. Моя інтерпретація 507полягає в тому, що сервер не має місця, а не те, що рахунок не має місця.
Патрік

11
Я згоден з Патріком. 5xxпомилки - це помилки, пов'язані з сервером.
Шон

10
418: "Я чайник", маючи на увазі, що місця для зберігання занадто мало (як чайник мало), а не велике, і, таким чином, немає місця.
Стів Конвес

22

Як зазначали інші, наявність сутності відповіді в коді помилки цілком допустимо.

Пам'ятайте, що помилки 5xx є стороною сервера, він також не може нічого змінити на свій запит, щоб передати запит. Якщо квота клієнта буде перевищена, це однозначно не є помилкою сервера, тому слід уникати 5xx.


Я б не погодився. Перевищення квоти було б помилкою сервера (5хх), оскільки: Запит клієнта є дійсним і був би успішним, якби за квотою, яка виключає 400 серій.
mikek3332002

3
Але сервер нічого поганого не зробив.
Charlie Schliesser

20

Існує два види помилок. Помилки програми та помилки HTTP. Помилки HTTP полягають у тому, щоб ваш обробник AJAX знав, що все пішло нормально і не слід його використовувати ні для чого іншого.

5xx помилка серверу

500 Internal Server Error
501 Not Implemented
502 Bad Gateway
503 Service Unavailable
504 Gateway Timeout
505 HTTP Version Not Supported
506 Variant Also Negotiates (RFC 2295 )
507 Insufficient Storage (WebDAV) (RFC 4918 )
509 Bandwidth Limit Exceeded (Apache bw/limited extension)
510 Not Extended (RFC 2774 )

2xx Успіх

200 OK
201 Created
202 Accepted
203 Non-Authoritative Information (since HTTP/1.1)
204 No Content
205 Reset Content
206 Partial Content
207 Multi-Status (WebDAV)

Однак, як ви розробляєте помилки програми, залежить від вас. Переповнення стека, наприклад , посилає об'єкт з response, dataі messageвластивостями. Я вважаю, що відповідь містить trueабо falseвказує на те, що операція пройшла успішно (зазвичай це стосується операцій запису). Дані містять корисну навантаження (зазвичай для операцій з читання), а повідомлення містить будь-які додаткові метадані або корисні повідомлення (наприклад, повідомлення про помилки, коли responseє false).


1
400 також корисно вказати на проблему в клієнтській програмі.
долмен

19

Я знаю, що це дуже пізно для вечірки, але зараз, у 2013 році, у нас є декілька типів засобів масової інформації, щоб висвітлювати обробку помилок у розповсюдженому (RESTful) способі. Див. "Vnd.error", application / vnd.error + json ( https://github.com/blongden/vnd.error ) та "Інформація про проблему для HTTP API", застосунок / проблема + json ( https: // інструменти. ietf.org/html/draft-nottingham-http-problem-05 ).


2
Дякуємо за посилання. Проблема draft-nottingham-http тепер є запропонованим стандартом: datatracker.ietf.org/doc/rfc7807
seanf

9

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

Надсилання відповіді на помилку в конверті HTTP 200 вводить в оману і змушує клієнта (api-споживача) проаналізувати повідомлення, швидше за все, нестандартним або власницьким способом. Це також неефективно - ви змусите своїх клієнтів щоразу аналізувати корисну навантаження HTTP, щоб зрозуміти "реальний" статус відповіді. Це збільшує обробку, додає затримки і створює середовище для клієнта, щоб помилитися.


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

3
Якщо ви отримаєте 200 ОК, ви можете також не розбирати його, залежно від правил вашого бізнесу. Справа не в тому, розбираємо ми це чи ні. Сенс у намірі - який намір 200 ОК? Ви пошкоджуєте намір, надсилаючи повідомлення про помилки, загорнуті в 200 ОК.
Кінгз

1
"який задум 200 ОК?" - вказівка ​​на успіх транспортного шару. На запит було успішно отримано і відповіли, лише проблема, пов’язана з додатком, не має нічого спільного з HTTP. +++ Якщо навпаки: надсилання 404 у світі REST означає, що щось не було знайдено, можливо, URL-адреса якраз неправильна або ресурс, який підлягає обробці, або щось інше не знайдено. Без розбору повідомлення ви не можете. ІМХО РЕСТ - це просто сполучення шарів.
maaartinus

Конфліктність - норма. Він надає вам синтаксис для вирішення, який відповідає вашій міркуванню, і дозволяє вам зосередитись на бізнес-шарі. Домовились про транспортні пізніші комісійні перевезення - ось, в чому полягала мета, - REST не був винайдений / запропонований одночасно з HTTP - він прийшов пізніше і просто вирішив використовувати існуючу інфраструктуру для представлення ДЕРЖАВ та їх ЗМІНИ.
Кінгз


5

Будь ласка, дотримуйтесь семантики протоколу. Використовуйте 2xx для успішних відповідей та 4xx, 5xx для відповідей на помилки - будь то винятки для вашого бізнесу чи інші. Якби використання 2xx для будь-якої відповіді було випадком використання за призначенням у протоколі, вони б не мали інших кодів статусу в першу чергу.


3

Не забувайте також про помилки 5xx, а також про помилки програми.

У цьому випадку, що з 409 (конфлікт)? Це передбачає, що користувач може усунути проблему, видаливши збережені ресурси.

Інакше 507 (не зовсім стандартно) також може працювати. Я б не використовував 200, якщо ви взагалі не використовуєте 200 для помилок.


-1

Якщо клієнтська квота перевищена, це помилка сервера, уникайте 5xx у цьому випадку.


2
Чому слід уникати помилок серії 5xx, коли вони стосуються помилок сервера?
mikek3332002

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