400 vs 422 odpowiedź na POST z danymi

Próbuję dowiedzieć się, jaki jest poprawny kod statusu w różnych scenariuszach z "REST-like" API, nad którym pracuję. Załóżmy, że mam punkt końcowy, który umożliwia POST ' ING zakupy w formacie JSON. Wygląda tak:

{
    "account_number": 45645511,
    "upc": "00490000486",
    "price": 1.00,
    "tax": 0.08
}

Co mam zwrócić, jeśli klient wyśle mi "sales_tax "(zamiast oczekiwanego"podatku"). Obecnie zwracam 400. Ale zacząłem w to wątpić. Czy naprawdę powinienem zwrócić 422? Chodzi mi o JSON (czyli obsługiwane) i jest poprawny JSON, po prostu nie zawiera wszystkich wymaganych pól.

Author: martijnn2008, 2013-04-21

9 answers

400 złe żądanie wydaje się teraz najlepszym kodem stanu HTTP/1.1 Dla Twojego przypadku użycia.

W momencie, gdy zadałeś sobie pytanie (i moja oryginalna odpowiedź), RFC 7231 nie było rzeczą; w tym momencie sprzeciwiłem się 400 Bad Request, ponieważ RFC 2616 powiedział (z naciskiem na moje):

Żądanie nie może być zrozumiane przez Serwer z powodu nieprawidłowej składni.

I żądanie, które opisujesz jest poprawne składniowo JSON zamknięte w poprawny składniowo HTTP, a więc serwer nie ma problemów ze składnią żądania.

Jednakże Jak zauważył Lee Saferite w komentarzach, RFC 7231, który przestarzały RFC 2616, nie zawiera tego ograniczenia :

Kod statusu 400 (Bad Request) wskazuje, że serwer nie może lub nie przetworzy żądania z powodu czegoś, co jest postrzegane jako błąd klienta (np. nieprawidłowa składnia żądania, Nieprawidłowe żądanie obramowanie wiadomości lub zwodnicze przekierowanie żądań).


Jednak, Przed tym ponownym sformułowaniem (lub jeśli chcesz się spierać o to, że RFC 7231 jest tylkoproponowanym standardem w tej chwili), 422 Unprocessable Entity nie wydaje sięnieprawidłowy kod statusu HTTP dla Twojego przypadku użycia, ponieważ jakwprowadzenie do RFC 4918 mówi: {7]}

Podczas gdy kody statusu dostarczone przez HTTP / 1.1 są wystarczające do opisz większość błędów napotkanych przez WebDAV metody, tam są pewne błędy, które nie należą starannie do istniejących kategorii. Ta specyfikacja definiuje dodatkowe kody stanu opracowane dla WebDAV metody (Sekcja 11)

I Opis 422 says:

Kod statusu 422 (Unprocessable Entity) oznacza serwer rozumie typ zawartości jednostki żądania (stąd 415 (nieobsługiwany typ nośnika) kod stanu jest nieodpowiedni), a składnia żądania encja jest poprawna (tak więc 400 (złe żądanie) kod stanu jest niewłaściwy) , ale nie był w stanie przetworzyć zawartego instrukcje.

(zwróć uwagę na odniesienie do składni; podejrzewam, że 7231 częściowo nie działa 4918)

To brzmi dokładnie jak twoja sytuacja, ale na wszelki wypadek, gdyby były jakieś wątpliwości, mówi:

Na przykład ten warunek błędu może wystąpić, jeśli XML ciało żądania zawiera dobrze uformowane (tzn. poprawne składniowo), ale semantycznie błędne instrukcje XML.

(Zamień " XML " na "JSON" i myślę, że możemy się zgodzić, że to twoja sytuacja)

Teraz niektórzy będą sprzeciwiać się, że RFC 4918 dotyczy "rozszerzeń HTTP dla Web Distributed Authoring and Versioning( WebDAV)" i że (prawdopodobnie) nie robisz nic związanego z WebDAV, więc nie powinieneś używać rzeczy z niego.

Biorąc pod uwagę wybór pomiędzy użyciem kodu błędu w oryginalnym standardzie, który wyraźnie nie obejmuje sytuacji, a jednym z rozszerzenia, które dokładnie opisuje sytuację, wybrałbym to drugie.

Ponadto, RFC 4918 sekcja 21.4 odnosi się do Iana Hypertext Transfer Protocol (HTTP) Status Code Registry, gdzie można znaleźć 422.

Proponuję, aby Klient HTTP lub serwer korzystali z dowolnego kodu statusu z tego rejestru, o ile robią to poprawnie.


Ale od HTTP/1.1, RFC 7231 ma trakcję, więc wystarczy użyć 400 Bad Request!

 313
Author: Kristian Glass,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-08-21 16:22:10

Aby odzwierciedlić stan na dzień 2015:

Behawioralnie zarówno kody odpowiedzi 400, jak i 422 będą traktowane tak samo przez klientów i pośredników, więc w rzeczywistości nie robi to konkretnej różnicy, której używasz.

Jednak spodziewałbym się, że 400 jest obecnie używane szerzej, a ponadto wyjaśnienia, które zapewnia httpbis spec sprawiają, że bardziej odpowiedni z dwóch kodów statusu:

  • Specyfikacja HTTPbis wyjaśnia intencję 400 nie tylko za błędy składniowe. Szersze wyrażenie "wskazuje, że serwer nie może lub nie przetworzy żądania z powodu czegoś, co jest postrzegane jako błąd klienta"jest teraz używane.
  • 422 jest konkretnie rozszerzeniem WebDAV i nie jest wymieniony w RFC 2616 ani w nowszej specyfikacjiHTTPbis .

Dla kontekstu, HTTPbis jest rewizją specyfikacji HTTP/1.1, która próbuje wyjaśnić obszary, które są niejasne lub niespójne. Po osiągnięciu status zatwierdzony zastąpi RFC2616.

 30
Author: Tom Christie,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-01-13 10:16:23

400 Bad Request to właściwy kod statusu HTTP dla Twojego przypadku użycia. Kod jest zdefiniowany przez HTTP / 0.9-1.1 RFC.

Żądanie nie może być zrozumiane przez serwer z powodu nieprawidłowego składnia. Klient nie powinien powtarzać żądania bez modyfikacje.

Http://tools.ietf.org/html/rfc2616#section-10.4.1

422 Unprocessable Entity {[2] } jest zdefiniowane przez RFC 4918-WebDav. Należy zauważyć, że istnieje niewielka różnica w porównaniu do 400, patrz cytowany tekst poniżej.

Ten warunek błędu może wystąpić, jeśli XML ciało żądania zawiera dobrze uformowane (tzn. poprawne składniowo), ale semantycznie błędne instrukcje XML.

Aby zachować jednolity interfejs, należy używać 422 tylko w przypadku odpowiedzi XML, a także wspierać wszystkie kody statusu zdefiniowane przez rozszerzenie Webdav, a nie tylko 422.

Http://tools.ietf.org/html/rfc4918#page-78

Zobacz też post na kodach statusu:

Błędem jest próba mapowania każdej części aplikacji " głęboko" do kodów statusu HTTP; w większości przypadków poziom szczegółowości można chęć celowania jest znacznie grubsza. w razie wątpliwości można używać ogólne kody stanu 200 OK, 400 Bad Request i 500 Internal Błąd serwisowy, gdy nie ma lepszego dopasowania .

Jak myśleć o kodach statusu HTTP

 25
Author: filip26,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-06-23 22:33:54

Nie ma poprawnej odpowiedzi, ponieważ zależy to od definicji "składni" dla Twojego żądania. Najważniejsze, że ty:

  1. używaj kodów odpowiedzi konsekwentnie
  2. Dołącz jak najwięcej dodatkowych informacji w treści odpowiedzi, aby pomóc programistom za pomocą interfejsu API dowiedzieć się, co się dzieje.=

Zanim wszyscy skoczą na mnie za to, że mówię, że nie ma tu dobrej lub złej odpowiedzi, pozwól mi wyjaśnić trochę o tym, jak doszedłem do wniosek.

W tym konkretnym przykładzie, pytanie OP dotyczy żądania JSON, które zawiera inny klucz niż oczekiwano. Obecnie otrzymana nazwa klucza jest bardzo podobna, z punktu widzenia języka naturalnego, do klucza oczekiwanego, ale jest ściśle inna, a zatem nie jest (zazwyczaj) rozpoznawana przez maszynę jako równoważna.

Jak powiedziałem powyżej, decydującym czynnikiem jest to, co oznacza składnia. Jeśli żądanie zostało wysłane z typem treści application/json, to tak, request is składniowo valid, ponieważ jest poprawną składnią JSON, ale nie semantycznie valid, ponieważ nie odpowiada oczekiwaniom. (przyjmując ścisłą definicję tego, co sprawia, że dany wniosek jest semantycznie ważny lub nie).

Jeśli z drugiej strony żądanie zostało wysłane z bardziej specyficznym niestandardowym typem zawartości, takim jak application/vnd.mycorp.mydatatype+json, który być może dokładnie określa, jakie pola są oczekiwane, to powiedziałbym, że żądanie może być łatwo niepoprawne składniowo, stąd odpowiedź 400.

W omawianym przypadku, ponieważ Klucz był błędny, a nie wartość, wystąpił składniabłąd jeśli istniała Specyfikacja dla tego, czym są poprawne klucze. jeśli nie było specyfikacji dla ważnych kluczy lub błąd miał wartość , to byłby to semantyczny błąd.

 11
Author: cdeszaq,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-01-31 19:24:07

Po pierwsze jest to bardzo dobre pytanie.

400 Bad Request-gdy w zapytaniu brakuje krytycznej informacji

Np. nagłówek autoryzacji lub nagłówek typu content. Co jest absolutnie wymagane przez serwer, aby zrozumieć żądanie. Może się to różnić w zależności od serwera.

422 Unprocessable Entity-gdy nie można przetworzyć ciała żądania.

To jest mniej poważne niż 400. Żądanie dotarło do serwera. Serwer potwierdził Prośba ma podstawową strukturę. Ale informacji w treści żądania nie można przetworzyć ani zrozumieć.

Np. Content-Type: application/xml gdy ciało żądania to JSON.

Oto artykuł z listą kodów stanu i ich wykorzystania w REST API. https://metamug.com/article/status-codes-for-rest-api.php

 4
Author: ,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-11-09 14:20:52

422 Unprocessable Entity Explained Aktualizacja: 6 Marca 2017

Co To Jest 422 Unprocessable Entity?

Kod statusu 422 występuje, gdy żądanie jest dobrze uformowane, jednak z powodu do błędów semantycznych nie można go przetworzyć. Ten status HTTP był wprowadzony w RFC 4918 i jest bardziej ukierunkowany na HTTP rozszerzenia dla Web Distributed Authoring and Versioning (WebDAV).

Istnieją pewne kontrowersje, czy deweloperzy powinien zwrócić klientowi błąd 400 vs 422 (więcej o różnicach pomiędzy obydwoma statusami poniżej). Jednak w większości przypadków jest to uzgodnione po tym stanie 422 powinien zostać zwrócony tylko wtedy, gdy obsługujesz WebDAV możliwości.

Słowo w słowo definicja kodu stanu 422 zaczerpnięta z sekcji 11.2 w RFC 4918 można przeczytać poniżej.

Kod statusu 422 (Unprocessable Entity) oznacza serwer rozumie typ zawartości jednostki żądania (stąd 415 (nieobsługiwany typ nośnika) kod stanu jest nieodpowiedni), a składnia encji żądania jest poprawna (a więc 400 (Bad Request) kod stanu jest niewłaściwy) , ale nie był w stanie przetworzyć zawartego instrukcje.

Definicja mówi dalej:

Na przykład ten warunek błędu może wystąpić, jeśli ciało żądania XML zawiera dobrze uformowane (tzn. poprawne składniowo), ale semantycznie błędne instrukcje XML.

400 vs 422 kody statusu

Złe błędy żądania wykorzystują kod statusu 400 i powinny być zwracane do klienta, jeżeli składnia żądania jest nieprawidłowa, zawiera nieprawidłowa ramka wiadomości żądania lub zwodniczy routing żądania. Ten kod stanu może wydawać się dość podobny do 422 unprocessable statusu podmiotu, jednak jedna mała informacja, która wyróżnia je fakt, że składnia encji żądania dla błąd 422 jest poprawny natomiast składnia żądania generującego a 400 błąd jest nieprawidłowy.

Użycie statusu 422 powinno być zarezerwowane tylko dla bardzo szczególnych przypadki użycia. W większości innych przypadków, gdy wystąpił błąd klienta z powodu do nieprawidłowej składni należy użyć statusu 400 Bad Request.

Https://www.keycdn.com/support/422-unprocessable-entity/

 3
Author: Clojurevangelist,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-07-13 05:06:56

Twoja sprawa: HTTP 400 jest właściwym kodem stanu dla twojej sprawy z perspektywy REST, ponieważ jego składniowo niepoprawny do wysłania sales_tax zamiast tax, chociaż jest to poprawny JSON. Jest to zwykle wymuszane przez większość struktur po stronie serwera podczas mapowania JSON na obiekty. Jednak niektóre implementacje REST ignorują Nowy key w obiekcie JSON. W takim przypadku, niestandardowa Specyfikacja content-type akceptująca tylko ważne pola może być wymuszona przez serwer.

Ideał Scenariusz dla 422:

W idealnym świecie, 422 jest preferowane i ogólnie akceptowalne wysyłanie jako odpowiedź, jeśli serwer rozumie typ zawartości jednostki żądania i składnia jednostki żądania jest poprawna, ale nie był w stanie przetworzyć danych, ponieważ ich semantycznie błędne.

Sytuacje 400 powyżej 422:

Pamiętaj, że kod odpowiedzi 422 jest rozszerzonym kodem statusu HTTP (WebDAV). Nadal istnieje kilka klientów HTTP / front-end biblioteki, które nie są przygotowane do obsługi 422. Dla nich jest to tak proste, jak "HTTP 422 jest zły, ponieważ nie jest to HTTP". Z punktu widzenia serwisu, 400 nie jest do końca konkretne.

W architekturze korporacyjnej usługi są wdrażane głównie na warstwach usług, takich jak SOA, IDM itp. Zazwyczaj obsługują wielu klientów, od bardzo starego klienta macierzystego do najnowszych klientów HTTP. Jeśli jeden z klientów nie obsługuje HTTP 422, opcje są takie, że prosząc Klienta o uaktualnienie lub Zmień kod odpowiedzi na HTTP 400 dla wszystkich. Z mojego doświadczenia wynika, że jest to obecnie bardzo rzadkie, ale wciąż możliwe. Dlatego przed podjęciem decyzji o kodach odpowiedzi HTTP zawsze wymagane jest dokładne zbadanie architektury.

Aby poradzić sobie z takimi sytuacjami, warstwy usług zwykle używają znacznika versioning lub setup configuration dla klientów ściśle zgodnych z HTTP, aby wysłać 400 i wysłać 422 dla reszty z nich. W ten sposób zapewniają wsparcie kompatybilności wstecznej dla istniejących konsumentów, ale w jednocześnie zapewnia nowym klientom możliwość korzystania z protokołu HTTP 422.


Najnowsza aktualizacja do RFC7321 mówi:

The 400 (Bad Request) status code indicates that the server cannot or
   will not process the request due to something that is perceived to be
   a client error (e.g., malformed request syntax, invalid request
   message framing, or deceptive request routing).

To potwierdza, że serwery mogą wysyłać HTTP 400 dla nieprawidłowego żądania. 400 nie odnosi się już tylko do błędu składni, jednak 422 nadal jest prawdziwą odpowiedzią, pod warunkiem, że klienci mogą sobie z tym poradzić.

 1
Author: YuVi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-06-04 15:18:31

Case study: GitHub API

Https://developer.github.com/v3/#client-errors

Może kopiowanie ze znanych API jest mądrym pomysłem:

Istnieją trzy możliwe typy błędów klienta w wywołaniach API, które otrzymują ciała żądań:

Wysłanie nieprawidłowego pliku JSON spowoduje wysłanie 400 błędnych żądań.

HTTP/1.1 400 Bad Request
Content-Length: 35

{"message":"Problems parsing JSON"}

Wysłanie błędnego typu wartości JSON spowoduje wysłanie 400 błędnych odpowiedzi na żądanie.

HTTP/1.1 400 Bad Request
Content-Length: 40

{"message":"Body should be a JSON object"}

Wysyłanie nieprawidłowe pola spowodują odpowiedź 422 nieprzetworzonych jednostek.

HTTP/1.1 422 Unprocessable Entity
Content-Length: 149

{
  "message": "Validation Failed",
  "errors": [
    {
      "resource": "Issue",
      "field": "title",
      "code": "missing_field"
    }
  ]
}
 0
Author: Ciro Santilli 新疆改造中心 六四事件 法轮功,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-09-17 09:02:03

Powinieneś zwrócić "200 OK" i w treści odpowiedzi umieścić komunikat o tym, co się stało z opublikowanymi danymi. Następnie do aplikacji należy zrozumienie komunikatu.

Chodzi o to, że kody statusu HTTP są dokładnie tym - kodami statusu HTTP. A te mają mieć znaczenie tylko na warstwie transportowej, a nie na warstwie aplikacji. Warstwa aplikacji naprawdę nigdy nie powinna wiedzieć, że HTTP jest używany. Jeśli przełączyłeś warstwę transport z HTTP w przypadku gołębi naprowadzających nie powinno to w żaden sposób wpływać na warstwę aplikacji.

Pozwól, że podam Ci nie wirtualny przykład. Powiedzmy, że zakochujesz się w dziewczynie, a ona cię kocha, ale jej rodzina przenosi się do zupełnie innego kraju. Podała ci swój nowy adres. Oczywiście, decydujesz się wysłać jej List miłosny. Więc piszesz swój list, wkładasz go do koperty, piszesz jej adres na kopercie, wkładasz pieczątkę i wysyłasz. Teraz rozważmy te scenariusze

    Zapomniałeś napisać nazwę ulicy. Otrzymasz nieotwarty list z wiadomością napisaną na nim, że adres jest zniekształcony. Schrzaniłeś wniosek, a Poczta odbierająca nie jest w stanie go obsłużyć. To odpowiednik otrzymania "400 złych próśb". Więc popraw adres i wyślij list jeszcze raz. Ale z powodu jakiegoś pecha kompletnie pomyliłeś nazwę ulicy. Dostaniesz list z powrotem z wiadomością, że adres nie istnieje. To odpowiednik "404 Not Found".
  1. poprawiasz adres ponownie i tym razem uda Ci się poprawnie napisać adres. Twoja dziewczyna odbiera list i odpisuje. To odpowiednik otrzymania "200 OK". Nie oznacza to jednak, że spodoba ci się to, co napisała w swoim liście. Oznacza to po prostu, że otrzymała Twoją wiadomość i ma dla ciebie odpowiedź. Dopóki nie otworzysz koperty i nie przeczytasz jej listu, nie wiesz, czy ona tęskni za tobą lub chce z Tobą zerwać.

W skrócie: zwracanie "200 OK" nie oznacza, że aplikacja serwera ma dla Ciebie dobrą wiadomość. To tylko oznacza, że ma jakieś wieści.

PS: kod stanu 422 ma znaczenie tylko w kontekście WebDAV. Jeśli nie pracujesz z WebDAV, to 422 ma dokładnie takie samo standardowe znaczenie jak każdy inny niestandardowy kod=, który jest none.

 -7
Author: GoFree,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-03-08 06:46:00