Usiłuję dowiedzieć się, jaki poprawny kod stanu zwraca w różnych scenariuszach za pomocą interfejsu API typu „REST”, nad którym pracuję. Powiedzmy, że mam punkt końcowy, który pozwala na dokonywanie zakupów POST w formacie JSON. To 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 zadawać sobie pytania na ten temat. Czy naprawdę powinienem zwrócić 422? Mam na myśli, że jest to JSON (który jest obsługiwany) i jest prawidłowy JSON, po prostu nie zawiera wszystkich wymaganych pól.
rest
http-status-codes
David S.
źródło
źródło
Odpowiedzi:
400 Błędne żądanie wydaje się teraz najlepszym kodem statusu HTTP / 1.1 dla twojego przypadku użycia.
W momencie twojego pytania (i mojej pierwotnej odpowiedzi) RFC 7231 nie było rzeczą; w którym momencie sprzeciwiłem się,
400 Bad Request
ponieważ RFC 2616 powiedział (z naciskiem mój):a opisywane przez ciebie żądanie jest poprawnym składniowo JSON zamkniętym w poprawnym składniowo HTTP, a zatem serwer nie ma problemów ze składnią żądania.
Jednak, jak wskazał Lee Saferite w komentarzach , RFC 7231, która przestarza RFC 2616, nie obejmuje tego ograniczenia :
Jednak przed tym ponownym sformułowaniem (lub jeśli chcesz spierać się o to, że RFC 7231 jest obecnie tylko proponowanym standardem),
422 Unprocessable Entity
nie wydaje się nieprawidłowy kod statusu HTTP dla twojego przypadku użycia, ponieważ ponieważ mówi wprowadzenie do RFC 4918:I opis
422
mówi:(Zwróć uwagę na odniesienie do składni; podejrzewam, że 7231 częściowo przestarza również 4918)
To brzmi dokładnie tak , jak twoja sytuacja, ale na wypadek wątpliwości, mówi dalej:
(Zamień „XML” na „JSON” i myślę, że możemy się zgodzić, że taka jest Twoja sytuacja)
Teraz niektórzy sprzeciwiają się temu, że RFC 4918 dotyczy „Rozszerzeń HTTP dla Web DistributedV Authoring and Versioning (WebDAV)” i że (prawdopodobnie) nie robisz nic związanego z WebDAV, więc nie powinieneś z tego korzystać.
Biorąc pod uwagę wybór między użyciem kodu błędu w oryginalnym standardzie, który wyraźnie nie obejmuje sytuacji, a jednym z rozszerzenia dokładnie opisującego sytuację, wybrałbym ten drugi.
Ponadto sekcja 21.4 RFC 4918 odnosi się do rejestru kodów statusu protokołu HTTP (IANA Hypertext Transfer Protocol) , w którym można znaleźć 422.
Proponuję, aby całkowicie uzasadnione było, aby klient lub serwer HTTP używał dowolnego kodu statusu z tego rejestru, o ile robi to poprawnie.
Ale od HTTP / 1.1 RFC 7231 ma przyczepność, więc po prostu użyj
400 Bad Request
!źródło
400 Nieprawidłowe żądanie jest poprawnym kodem stanu HTTP dla twojego przypadku użycia. Kod jest zdefiniowany przez HTTP / 0.9-1.1 RFC.
http://tools.ietf.org/html/rfc2616#section-10.4.1
422 Obiekt nieprzetworzony jest zdefiniowany w RFC 4918 - WebDav. Zauważ, że istnieje niewielka różnica w porównaniu do 400, patrz cytowany tekst poniżej.
Aby zachować jednolity interfejs, powinieneś używać 422 tylko w przypadku odpowiedzi XML, a także obsługiwać wszystkie kody statusu zdefiniowane przez rozszerzenie Webdav, a nie tylko 422.
http://tools.ietf.org/html/rfc4918#page-78
Zobacz także post Mark Nottingham na temat kodów statusu:
Jak myśleć o kodach stanu HTTP
źródło
The following status codes are added to those defined in HTTP/1.1 [RFC2616].
Aby odzwierciedlić status z 2015 r .:
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 konkretnego różnicy, której używasz.
Spodziewałbym się jednak, że 400 będzie obecnie używanych w szerszym zakresie, a ponadto wyjaśnienia dostarczone przez specyfikację HTTPbis sprawiają, że jest bardziej odpowiedni z dwóch kodów statusu:
W kontekście, HTTPbis jest wersją specyfikacji HTTP / 1.1, która próbuje wyjaśnić obszary, które są niejasne lub niespójne. Po osiągnięciu statusu zatwierdzenia zastąpi RFC2616.
źródło
Studium przypadku: GitHub API
https://developer.github.com/v3/#client-errors
Może kopiowanie ze znanych interfejsów API to mądry pomysł:
źródło
Nie ma poprawnej odpowiedzi, ponieważ zależy to od definicji „składni” dla twojego żądania. Najważniejsze jest to, że:
Zanim wszyscy podskoczą za mną, mówiąc, że nie ma tutaj dobrej lub złej odpowiedzi, pozwólcie, że wyjaśnię trochę, jak doszedłem do wniosku.
W tym konkretnym przykładzie pytanie OP dotyczy żądania JSON, które zawiera inny klucz niż oczekiwano. Teraz otrzymana nazwa klucza jest bardzo podobna, z punktu widzenia języka naturalnego, do oczekiwanego klucza, ale jest ściśle inna i dlatego (zwykle) nie jest rozpoznawana przez maszynę jako równoważna.
Jak powiedziałem powyżej, decydującym czynnikiem jest składnia . Jeśli żądanie zostało wysłane z typem treści
application/json
, to tak, żądanie jest poprawne składniowo, ponieważ jest poprawną składnią JSON, ale nie semantycznie poprawne , ponieważ nie pasuje do oczekiwanych. (zakładając ścisłą definicję tego, co powoduje, że dane zapytanie jest semantycznie ważne, czy nie).Jeśli natomiast żądanie zostało wysłane z bardziej szczegółowym niestandardowym typem treści, takim jak
application/vnd.mycorp.mydatatype+json
ten, być może dokładnie określa, jakich pól należy się spodziewać, to powiedziałbym, że żądanie może być łatwo niepoprawne pod względem składniowym, stąd odpowiedź 400.W omawianym przypadku, ponieważ klucz był nieprawidłowy, a nie wartość , wystąpił błąd składniowy, jeśli istniała specyfikacja prawidłowych kluczy. Jeśli nie podano specyfikacji poprawnych kluczy lub błąd miał wartość , byłby to błąd semantyczny .
źródło
https://www.keycdn.com/support/422-unprocessable-entity/
źródło
Twoja sprawa:
HTTP 400
jest właściwym kodem stanu dla Twojej sprawy z punktu widzenia REST, ponieważsales_tax
zamiast tego jest niepoprawny pod względem składniowymtax
, mimo że jest to prawidłowy JSON. Jest to zwykle wymuszane przez większość frameworków po stronie serwera podczas mapowania JSON na obiekty. Istnieją jednak niektóre implementacje REST, które ignorują nowekey
w obiekcie JSON. W takim przypadku niestandardowacontent-type
specyfikacja, która akceptuje tylko prawidłowe pola, może zostać wymuszona po stronie serwera.Idealny scenariusz dla 422:
W idealnym świecie 422 jest preferowane i ogólnie akceptowalne do wysłania jako odpowiedź, jeśli serwer rozumie typ zawartości encji żądania, a składnia encji żądania jest poprawna, ale nie była w stanie przetworzyć danych, ponieważ jest semantycznie błędna.
Sytuacje 400 powyżej 422:
Pamiętaj, że kod odpowiedzi 422 jest rozszerzonym kodem statusu HTTP (WebDAV). Nadal istnieją niektóre klienty HTTP / biblioteki frontonu, które nie są przygotowane do obsługi 422. Dla nich jest to tak proste, jak „HTTP 422 jest zły, ponieważ to nie HTTP” . Z punktu widzenia usług 400 nie jest dość specyficzne.
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 natywnego do najnowszych klientów HTTP. Jeśli jeden z klientów nie obsługuje protokołu HTTP 422, dostępne opcje to poproszenie klienta o aktualizację lub zmianę kodu odpowiedzi na HTTP 400 dla wszystkich. Z mojego doświadczenia wynika, że obecnie jest to bardzo rzadkie, ale wciąż jest możliwe. Dlatego przed podjęciem decyzji o kodach odpowiedzi HTTP zawsze należy dokładnie przestudiować architekturę.
Aby poradzić sobie z taką sytuacją, warstwy usług zwykle używają
versioning
lub konfigurująconfiguration
flagę dla klientów o ścisłej zgodności HTTP, aby wysłać 400, a 422 resztę. W ten sposób zapewniają one kompatybilność wsteczną dla istniejących klientów, ale jednocześnie zapewniają nowym klientom możliwość korzystania z protokołu HTTP 422.Najnowsza aktualizacja RFC7321 mówi:
Potwierdza to, że serwery mogą wysłać HTTP 400 w przypadku nieprawidłowego żądania. 400 nie odnosi się już tylko do błędu składniowego , jednak 422 nadal jest prawdziwą odpowiedzią, pod warunkiem, że klienci będą w stanie to obsłużyć.
źródło
Po pierwsze, jest to bardzo dobre pytanie.
400 Błędne żądanie - gdy w żądaniu brakuje krytycznej informacji
np. nagłówek autoryzacji lub typ treści. Który jest absolutnie wymagany przez serwer do zrozumienia żądania. Może się to różnić w zależności od serwera.
422 Nieprzetworzona jednostka - gdy nie można przeanalizować treści żądania.
Jest to mniej poważne niż 400. Żądanie dotarło do serwera. Serwer potwierdził, że żądanie ma prawidłową podstawową strukturę. Ale informacji w treści żądania nie można przeanalizować ani zrozumieć.
na przykład
Content-Type: application/xml
gdy treść żądania to JSON.Oto artykuł zawierający listę kodów stanu i jego zastosowania w interfejsach API REST. https://metamug.com/article/status-codes-for-rest-api.php
źródło
Powinieneś faktycznie zwrócić „200 OK”, a w treści odpowiedzi zamieścić komunikat o tym, co się stało z opublikowanymi danymi. Następnie Twoja aplikacja musi zrozumieć komunikat.
Chodzi o to, że kody stanu HTTP są dokładnie takie - kody stanu HTTP. I mają one mieć znaczenie tylko w warstwie transportowej, a nie w warstwie aplikacyjnej. Warstwa aplikacji nigdy nie powinna nawet wiedzieć, że używany jest HTTP. Jeśli zmieniłeś warstwę transportową z HTTP na Homing Pigeons, nie powinno to w żaden sposób wpływać na warstwę aplikacji.
Dam ci nie-wirtualny przykład. Powiedzmy, że zakochałeś się w dziewczynie, która kocha cię z powrotem, ale jej rodzina przenosi się do zupełnie innego kraju. Daje ci swój nowy adres ślimaka. Oczywiście decydujesz się wysłać jej list miłosny. Więc piszesz list, wkładasz go do koperty, zapisujesz jej adres na kopercie, kładziesz na niej znaczek i wysyłasz. Rozważmy teraz te scenariusze
W skrócie: Zwrócenie „200 OK” nie oznacza, że aplikacja serwera ma dla Ciebie dobre wieści. Oznacza to tylko, że ma jakieś wiadomości.
PS: Kod statusu 422 ma znaczenie tylko w kontekście WebDAV. Jeśli nie pracujesz z WebDAV, 422 ma dokładnie takie samo standardowe znaczenie, jak każdy inny niestandardowy kod = który nie jest żaden.
źródło