Який код відповіді статусу HTTP я повинен використовувати, якщо в запиті відсутній необхідний параметр?


Відповіді:


387

Статус 422 видається найбільш підходящим на основі специфікації .

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

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

UPDATE @DavidV правильно вказує, що ця специфікація призначена для WebDAV, а не основного HTTP. Але деякі популярні API, які не WebDAV, так чи інакше використовують 422, через відсутність кращого коду статусу ( див. Це ).


2
IMO Я би використовував це, коли значення в рядку запиту було невірним, а не тоді, коли було додаткове значення або відсутнє значення. тобто. Очікуємо електронну пошту та її значення - "123123"
Дерек

2
Я схильний вважати параметри GET і POST як підпис методу шляху URL, тому 404 має для мене сенс. У API RESTful, призначений для громадського споживання, доцільно повертати відсутні / додаткові параметри. У контексті URL-адреси параметри рядка запиту, як правило, важливі для ідентифікації ресурсу, а додаткові чи відсутні параметри являють собою ресурс, який не існує, без будь-яких припущень. Звичайно, існують компроміси з надійністю, будучи явними, а необов'язкові параметри роблять ресурс потенційно настільки ж вразливим до мовчазних помилок. Тоді є зручність використання ...
Дерек Ліц

13
Специфікація, на яку посилається, призначена для WebDAV, і не є стандартом HTTP.
Давид V

1
@Kelvin Дякуємо, що вказали на цій публікації в блозі. Корисно побачити, що, наприклад, Twitter використовує 422. Я думаю, що відповідь може бути кращою, якщо ви уточните, що специфікація є WebDAV у першому рядку. Коли я вперше прочитав вашу відповідь, я подумав, що ви маєте на увазі стандартну специфікацію HTTP, поки я не перейшов за посиланням.
Давид V

3
Про це варто прочитати: bennadel.com/blog/… Я також не використовував би 422 для відсутнього парама. Я думаю, що 400це більш доречно.
Зельфір Кальтшталь

184

Я не впевнений, що є встановлений стандарт, але я б використав 400 Bad Request , який містить останні специфікації HTTP (з 2014 року) таким чином :

6.5.1. 400 Поганий запит

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


65
400 Bad Requestозначає, що вказує на проблеми на рівні протоколу, а не на семантичні помилки. Якщо ми збираємося викрасти коди статусу HTTP, щоб вказати на помилки на рівні програми (а не на рівні протоколу), чому б не пройти весь шлях і просто використовувати 412?
Метт Зуковський

36
Впровадження Google OAuth 1.0 погоджується з цією відповіддю. A 400 Відповідь дається , коли параметри POST відсутні або НЕ підтримуються: code.google.com/apis/accounts/docs/OAuth_ref.html
Том

1
@ matt-zukowski: "412: Передумова, задана в одному або декількох полях заголовка запиту, оцінена як помилкова, коли вона була протестована на сервері." від RFC2616 - Якщо це POST, параметри знаходяться в тілі запиту, а не полях-заголовках запиту. Технічно метод GET надсилає свої параметри в заголовки запитів, але замість цього я краще матиму певну послідовність?
понеділок

6
@MattZukowski 400 - код статусу рівня програми. Якщо ви подивитесь на переформулювання в проекті версії RFC 7231, ви побачите це. На жаль, формулювання в останній версії не так зрозуміле, оскільки автор останніх змін також винайшов 422.
Даррел Міллер

9
@DarrelMiller має рацію ( пряма посилання ): "Код стану 400 (поганий запит) вказує на те, що сервер не може або не обробляє запит через те, що сприймається як помилка клієнта (наприклад, неправильний синтаксис запиту, недійсне повідомлення запиту обрамлення або оманливе направлення запиту). " Залежно від семантики та очікувань щодо розширюваності (чи вдасться одного дня надіслати запит без параметра?), То лише стандартні HTTP та 4004 здаються доречними. Інше, придумайте новий код для свого API, але не перевантажуйте семантику.
TNE

31

WCF API в .NET ручках відсутні параметри, повертаючи HTTP 404«Endpoint Not Found» помилка при використанні WebHttpBinding .

Це 404 Not Foundможе мати сенс, якщо ви врахуєте ім'я свого методу веб-служби разом з його підписом параметра. Тобто, якщо ви відкриєте метод веб-сервісу LoginUser(string, string)і ви подали запит LoginUser(string), останній не знайдеться.

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

10.4.5 404 Не знайдено

Сервер не знайшов нічого, що відповідає Request-URI. Не вказується, чи є стан тимчасовим чи постійним.

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

10.4.1 400 Поганий запит

Сервер не міг зрозуміти запит через неправильний синтаксис. Клієнт НЕ повинен повторювати запит без змін.


Це те, що робить CherryPy за замовчуванням.
Дерек Ліц

А як щодо обробки запиту на пошту, коли ви приймаєте модель, а частина моделі відсутня? У такому випадку ви не отримаєте 404. Натомість ви отримуєте модель, яка не є дійсною, якщо я не помиляюся, і вам доведеться вирішити, що робити зараз.
Шейн Кортрілль

1
Ця інтерпретація здається розтяжкою і виражає RPC, а не REST pov. URI - це ідентифікатор, він існує і знайдений. Те, що надсилається в тілі, не є частиною ідентифікатора ресурсу. 422 є більш доречним.
Йона

404 - правильна відповідь, просто відредагуйте деякі URL-адреси в Інтернеті, щоб знайти консенсус!
jenson-button-event

8

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


7

В одному з наших проектів API ми вирішуємо встановити статус 409 деякому запиту, коли ми не можемо повністю заповнити його на 100% через відсутність параметра.

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

Довідка: w3.org/Protocols/

Таким чином, серед інших відповідей, таких як 400 або 404, ми вибрали 409, щоб забезпечити необхідність перегляду деяких записок у запиті, які корисні для налаштування нового і правильного запиту.

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

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


2
Це явно неправильно. 409 стосується проблем з одночасністю, оскільки @ MaximeGélinas вказує АБО ситуації, коли ресурс уже присутній, а дублікати не дозволені.
gimlichael

За специфікацією "Код стану 409 (конфлікт) вказує, що запит не вдалося виконати через конфлікт із поточним станом цільового ресурсу.". Використовувати його для відсутнього параметра просто неправильно; це зовсім інша помилка.
Марк Амері

5

Я зазвичай іду на 422 (Недоступний об'єкт), якщо щось у необхідних параметрах не відповідає тому, що потрібно кінцевій точці API (наприклад, занадто короткий пароль), але для відсутнього параметра я б пішов на 406 (Неприйнятно).


8
Ну, 406 Неприйнятний використовується із заголовком Accept (якщо сервер не може надіслати відповідь, клієнт зрозуміє). "Ресурс, ідентифікований запитом, здатний генерувати лише відповіді, які мають змістові характеристики, неприйнятні відповідно до заголовків прийняття, надісланих у запиті." . Я затримався на 422, оскільки немає "правильного" вибору з поточною специфікацією: - /
JakubKnejzlik

Використовувати для цього 406 - неправильно. Код 406 не означає, що запит був неприйнятним; це означає, що ви не можете задовольнити запит, оскільки відповіді, які ви можете надати, - це відповіді, які клієнт визнає неприйнятними на основі заголовків Accept, надісланих у запиті. (Наприклад, запит включений Accept-Language: de, вказуючи, що він прийме відповіді лише німецькою мовою, але єдині версії запитуваного документа, які є у вашому сервері, доступні англійською або французькою мовами.) Використання його для вказівки відсутнього параметра в запиті невірно, за визначенням у спец.
Марк Амері

3

Для тих, хто цікавиться, Spring MVC (принаймні 3.x) повертає 400 у цьому випадку, що мені здається неправильним.

Я перевірив кілька URL-адрес Google (account.google.com) та видалив необхідні параметри, і вони, як правило, повертають 404 у цьому випадку.

Я б скопіював Google.


18
Оскільки Google робить це, це не означає автоматично, що Google робить це правильно!
rve

4
Я погоджуюсь, не обов'язково "правильно", але іноді те, що правильно і сенс - це дві різні речі. Так чи інакше ... до читача :)
Нероманс

Деякий API Google повертає 400, наприклад , github.com/google/google-api-nodejs-client/issues/404
Dennis

що неправильно (і чому весна mvc не відповідає
jax-

3

Можна стверджувати, що a 404 Not Foundслід використовувати, оскільки вказаний ресурс не вдалося знайти.


3
Це поведінка за замовчуванням Java JAX-RS, коли параметр запиту не може бути перетворений у відповідний тип даних. Я з цим не згоден. Знайдено ресурс WAS: параметри запиту призначені для фільтрації ресурсу, а одному з фільтрів було надано неприйнятне значення. Я думаю, що це відповідає 422 найближчим об'єктам, що не переробляються, і 400 поганим запитом другого найближчого.
Райан

його поведінка за замовчуванням jax-rs, тому що це правильна поведінка!
jenson-button-event

Використання 404 є розумним, коли параметр рядка запиту призначений для ідентифікації ресурсу, було вказано значення, але це значення не відповідає ресурсу, який існує - наприклад, якщо ви запитуєте example.com/show-user -profile? user_id = 123, а користувач 123 не існує. Але це не те, про що ставилося це питання; йшлося про сценарій, коли необхідний параметр повністю опущений. Я не бачу, як це відповідає визначеному ресурсу, який не можна знайти.
Марк Амерді

2

Я часто використовую заборонену помилку 403. Аргументація полягає в тому, що запит був зрозумілий, але я не збираюся робити так, як його просили (бо все не так). Суб'єкт відповідей пояснює, що не так, тому якщо відповідь - це HTML-сторінка, повідомлення про помилки знаходяться на сторінці. Якщо це відповідь JSON або XML, інформація про помилку знаходиться там.

Від rfc2616 :

10.4.4 403 Заборонено

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


4
Спочатку добре звучить, хоча я, природно, асоціюю це з помилками аутентифікації чи дозволу. Крім того, специфіка натякає на це, де йдеться, "якщо сервер не хоче зробити цю інформацію доступною для клієнта". Також 404 може бути кращим варіантом. Я б
попрямував

21
Це жахлива ідея, навіть якщо це технічно добре. 403 універсально використовується для автентичних відповідей на відмову, і ви заплутаєте пекло своїх клієнтів, якщо спробуєте використовувати це для вказівки помилок параметрів. Наприклад, Twitter робить це - 403 використовується як при наданні недійсних облікових даних OAuth, так і тоді, коли з вашим запитом щось семантично не відповідає - і це постійне джерело плутанини для клієнтів API.
Метт Зуковський

1
@MattZukowski добре, це просто неправильно. Специфікація каже Authorization will not help, тому Twitter не повинен надсилати це для недійсних облікових даних OAuth.
торвін

@torvin 401 Unauthorizedзамість цього повинен надсилати Twitter . Однак ви можете зрозуміти, чому вони цього не роблять, якщо подивитися на описи цих двох кодів документів MDN , які дуже схожі.
Agi Hammerthief

-1

Просто для використання ASP.NET Core в якості посилання або прикладу, ASP.NET Core дозволяє вам підробляти контролер з діями, саме так виглядає дія "Деталі".

    // GET: Cars/Details/5
    public async Task<IActionResult> Details(int? id)
    {
        if (id == null)
        {
            return NotFound();
        }

        var car = await _context.Cars.FirstOrDefaultAsync(m => m.CarId == id);
        if (car == null)
        {
            return NotFound();
        }

        return View(car);
    }

Якщо параметр idне встановлений, він повертає 404 Not Found.


-5

Поверніть 404 - значить ресурс не вдалося знайти.

Спробуйте відредагувати URL-адресу сайту, який містить ідентифікатор. Я спробував кілька:

  • випуск gitub repo
  • сторінка злиття
  • перегляд продукту Amazon
  • лістинг на ebay
  • Стаття новин BBC

Всі повертаються 404, тому що ті розробники правильно інтерпретують стандарт, на що тут відповіді та багатьох інших немає.


1
Я вважаю, що більшість розробників визначають "параметр" як одну з пар імен / значень у рядку запиту або форму тіла POST. Запит на видачу Github repo не містить цього.
Келвін

@Kelvin ми, розробники, також містять у списку параметри шляху. якщо будь-який параметр url є обов'язковим, представляє розташування ресурсу і не включається, то 404 слід повернути. Це виключає requestBody.
jenson-button-event

-6

Я б пішов з 403.

Від RFC 2616 - протокол передачі гіпертексту - HTTP / 1.1

403 Заборонено

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

У своїй відповіді слід описати причину невдачі. Якщо ви віддаєте перевагу цього не робити, просто використовуйте 404.


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