Powiedz, że mam punkt końcowy REST, który przyjmuje liczbę całkowitą jako parametr:
/makeWaffles?numberOfWaffles=3
W tym przypadku chcę, aby liczba była dodatnia, ponieważ nie mogę zrobić ujemnej liczby gofrów (a żądanie 0 gofrów to strata czasu). Chcę więc odrzucić każde żądanie, które nie zawiera dodatniej liczby całkowitej. Chcę również odrzucić żądanie, które przekracza pewną maksymalną liczbę całkowitą (powiedzmy na razie, że jest to MAX_INTEGER).
W przypadku, gdy ktoś zażąda nie dodatniej liczby gofrów, czy powinienem zwrócić status HTTP 400 (Błędne żądanie)? Moje pierwsze zdanie brzmi „tak”: nie jest to dla mnie prawidłowy numer, aby zrealizować prośbę. Jednak RFC nie wymienia reguł biznesowych jako powodu do jego rzucenia:
Kod statusu 400 (Błędne żądanie) wskazuje, że serwer nie może lub nie przetworzy żądania z powodu czegoś, co jest postrzegane jako błąd klienta (np. Źle sformułowana składnia żądania, nieprawidłowe sformułowanie komunikatu żądania lub oszukańczy routing żądania).
Reguła biznesowa nie mieści się w żadnym z tych trzech przykładów. Jest poprawny pod względem składniowym, ma odpowiednie ramy i nie jest zwodniczym routingiem żądań.
Czy powinienem więc zwrócić status HTTP 400 (Błędne żądanie), jeśli parametr jest poprawny pod względem składniowym, ale narusza regułę biznesową? Czy jest bardziej odpowiedni status do zwrócenia?
źródło
Odpowiedzi:
To wielkie pytanie i wciąż bardzo aktualne, biorąc pod uwagę kontekst historyczny (i pozornie sprzeczne definicje) kodów powrotu HTTP. Nawet wśród odpowiedzi na to pytanie istnieją sprzeczne definicje. Można to wyjaśnić, poruszając się chronologicznie.
RFC 2616 (czerwiec 1999)
Począwszy od tego dokumentu RFC, ten kod statusu został zastosowany wyłącznie do nieprawidłowo składniowych żądań. Wystąpiła luka w kodach statusu dla weryfikacji semantycznej. Tak więc, kiedy pojawiła się RFC 4918, narodził się nowy kod.
RFC 4918 (czerwiec 2007)
422 Jednostka nieprzetworzona została utworzona w celu wypełnienia luki w sprawdzaniu poprawności semantycznej w oryginalnej specyfikacji kodów statusu 4xx. Jednak w 2014 r. Pojawiła się kolejna istotna specyfikacja RFC, która uogólniła 400, aby nie była już specyficzna dla składni .
RFC 7231 (czerwiec 2014, wyraźnie przestarzałe RFC 2616)
Zauważ, że opis 422 mówi, że przyczyną 400 jest nieodpowiednia przyczyna, ponieważ 400 (od RFC 2616) powinno być zwracane tylko dla składni złych żądań. Jednak od RFC 7231 ścisła definicja błędu składniowego nie ma już zastosowania do 400 .
Wracając do pytania: chociaż 422 jest technicznie bardziej szczegółowe, biorąc pod uwagę ten kontekst, mogłem zobaczyć, że 400 lub 422 są używane do semantycznej weryfikacji parametrów API. Waham się przed użyciem 422 we własnych interfejsach API, ponieważ definicja 422 jest w tym momencie technicznie nieaktualna (chociaż nie wiem, czy jest to oficjalnie rozpoznane). Artykuł przywołany w odpowiedzi Frana, który zachęca do korzystania z 422, został napisany w 2012 r., Dwa lata przed tym, jak RFC 7231 wyjaśnił HTTP 400. Pamiętaj o standaryzacji jednego lub drugiego.
źródło
Przeczytałem pierwszą odpowiedź i tak naprawdę się z nią nie zgadzałem, ponieważ, przynajmniej w moim czytaniu, zła prośba (400) oznacza: „Nie mogę nawet obsłużyć twojej prośby, ponieważ coś jest zasadniczo nie tak”. I znalazłem ten post, który uzasadnia zwrot 422.
z IETF
422 Nieprzetworzona jednostka (WebDAV; RFC 4918) Żądanie zostało poprawnie sformułowane, ale nie można było go zrealizować z powodu błędów semantycznych
To wydaje się być bardziej odpowiednią odpowiedzią, ponieważ twoje zapytanie jest poprawnie sformułowane, ale nie spełnia twoich reguł sprawdzania poprawności.
źródło
Tak, dane wejściowe, które nie są zgodne z dorozumianą umową punktu końcowego, to „coś, co jest postrzegane jako błąd klienta” i powinno zwrócić wartość 400.
Wyjątkiem jest sytuacja, w której reguła biznesowa jest związana z bezpieczeństwem (wtedy
401 Unauthorized
lub403 Forbidden
byłoby lepiej). Alternatywnie, jeśli wysłanie 400 spowoduje wyciek informacji o istnieniu czegoś, a wtedy404 Not Found
może być bardziej odpowiednie.źródło
Nie, nie powinieneś. Kody HTTP są przeznaczone dla warstwy HTTP Twojej aplikacji. Reguły biznesowe mają zupełnie inną warstwę i są specyficzne dla aplikacji, dlatego musisz wymyślić własny „protokół”.
Wyobraź sobie, że dzieje się apokalipsa i musisz przełączyć się z protokołu HTTP na używanie gołębi. Gołębie nie mają żadnych kodów powrotu, więc trzeba by zmienić warstwę biznesową, aby się do tego dostosować. Ale twoja firma tak naprawdę się nie zmieniła, więc nie musisz zmieniać warstwy biznesowej. Pokazuje ścisłe połączenie tych dwóch warstw (transport i biznes).
Wróć do pytania: Powinieneś zwrócić „200 OK” z treścią opisującą, co się stało z żądaniem. Specyfikacja wyraźnie mówi:
https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.2.1 .
Czy żądanie HTTP się powiodło? Tak, serwer WWW wie, co zrobić z tym żądaniem (np. Przekazać je do części aplikacji serwera). Następnie serwer WWW przekazuje to żądanie do części serwerowej aplikacji, która pobiera dane POSTed, przetwarza je (weryfikuje je w twoim przypadku) i zwraca normalną odpowiedź (w treści odpowiedzi HTTP) do części klienta aplikacji . Ta odpowiedź z części serwerowej aplikacji może brzmieć „Świetnie, dane, które mi przesłałeś, są prawidłowe” lub „Przykro mi, dane, które przesłałeś, są nieprawidłowe”. Rozumienie, co oznacza odpowiedź, zależy od części aplikacji klienta.
PS: „400 Błędne żądanie” oznacza, że serwer internetowy nie zrozumiał, czego od niego oczekujesz. Oznacza to, że część aplikacji na serwerze nie otrzymała nawet żądania. A przynajmniej tak to powinno oznaczać :-)
EDYCJA : Właśnie zdałem sobie sprawę, że wykonujesz żądanie GET, a nie POST. To zły pomysł, ponieważ GET nie powinien zmieniać stanu aplikacji. GET ma po prostu pobierać dane z serwera. Ale w swojej prośbie zmieniasz stan aplikacji, więc naprawdę powinieneś używać POST.
źródło
Nie jestem pewien, czy wszystko się zgodzi, ale używamy 409 - Konflikt. Wiele osób twierdzi, że 409 jest bardziej konfliktem ze stanem systemu, ale przyjęliśmy interpretację, że konflikt wartości danych poza akceptowanym zakresem może zostać naprawiony przez żądającego i dopuszczalne użycie 409. 422 Myślę, że uzasadnione byłoby żądanie jest poprawnie utworzony, ale nie może być przetwarzany zgodnie z żądaniem. Wybieram jednak, jeśli nie chcesz wdrożyć mnóstwa odpowiedzi, samo podanie 400 jest nadal dopuszczalne.
źródło