Na przykład uruchamiasz żądanie GET, users/9
ale nie ma użytkownika o identyfikatorze nr 9. Jaki jest najlepszy kod odpowiedzi?
- 200 OK
- 202 Zaakceptowano
- 204 Brak treści
- 400 złych wniosków
- 404 Nie Znaleziono
rest
http
api-design
IMB
źródło
źródło
Odpowiedzi:
TL; DR: Użyj
404
Zobacz ten blog . Wyjaśnia to bardzo dobrze.
Podsumowanie komentarzy na blogu
204
:204 No Content
nie jest szczególnie przydatny jako kod odpowiedzi dla przeglądarki (chociaż zgodnie ze specyfikacją HTTP przeglądarki muszą rozumieć to jako kod odpowiedzi „nie zmieniaj widoku”).204 No Content
jest jednak bardzo przydatny dla serwisów internetowych ajax, które mogą chcieć wskazać sukces bez konieczności zwracania czegoś. (Szczególnie w przypadkach takich jakDELETE
lubPOST
s, które nie wymagają informacji zwrotnej).Dlatego odpowiedzią na twoje pytanie jest użycie
404
w twoim przypadku.204
to specjalistyczny kod odpowiedzi, którego nie powinieneś często wracać do przeglądarki w odpowiedzi naGET
.Inne kody odpowiedzi, które są jeszcze mniej odpowiednie niż
204
i404
:200
należy zwrócić wraz z ciałem tego, co udało się pobrać. Nieodpowiednie, gdy pobierany element nie istnieje.202
jest używany, gdy serwer rozpoczął pracę nad obiektem, ale obiekt nie jest jeszcze w pełni gotowy. Z pewnością tak nie jest. Nie rozpocząłeś ani nie rozpoczniesz budowy użytkownika 9 w odpowiedzi naGET
żądanie. To łamie wszelkie zasady.400
jest używany w odpowiedzi na źle sformatowane żądanie HTTP (na przykład zniekształcone nagłówki http, niepoprawnie uporządkowane segmenty itp.). Prawie na pewno zostanie to obsłużone przez dowolne frameworki, których używasz. Nie powinieneś sobie z tym radzić, chyba że piszesz własny serwer od zera. Edycja : nowsze wersje RFC pozwalają teraz na użycie 400 dla semantycznie niepoprawnych żądań.Szczególnie pomocny jest opis Wikipedii kodów stanu HTTP . Możesz również zobaczyć definicje w dokumencie HTTP / 1.1 RFC2616 na www.w3.org
źródło
204
kodu odpowiedzi (Brak treści)./badurl
lub/user/9
gdy taki użytkownik nie istnieje. Deweloper może pomóc, dodając lepszą przyczynę niż „Nie znaleziono”, ale nie jest to wymagane.The server has not found anything matching the Request-URI
. Serwer WWW / aplikacji w rzeczywistości znalazł AKCJĘ pasującą do identyfikatora URI żądania, chociaż serwer db nie. Jednak mówi równieżThis status code is commonly used when [...] no other response is applicable
, więc myślę, że nieco to potwierdza jego użycie (nawet jeśli się z tym nie zgadzam / lubię).Zdecydowanie sprzeciwiam się 404 na rzecz 204 lub 200 z pustymi danymi. Lub przynajmniej jeden powinien użyć encji odpowiedzi z 404.
Żądanie zostało odebrane i poprawnie przetworzone - wywołało kod aplikacji na serwerze, dlatego nie można tak naprawdę powiedzieć, że był to błąd klienta, a zatem cała klasa kodów błędów klienta (4xx) nie pasuje.
Co ważniejsze, 404 może się zdarzyć z wielu przyczyn technicznych. Np. Aplikacja jest tymczasowo dezaktywowana lub odinstalowywana na serwerze, problemy z połączeniem proxy i tym podobne. Dlatego klient nie może rozróżnić między 404, co oznacza „pusty zestaw wyników”, a 404, co oznacza, że „nie można znaleźć usługi, spróbuj ponownie później”.
Może to być śmiertelne: wyobraź sobie usługę księgową w Twojej firmie, która zawiera listę wszystkich pracowników, którzy są objęci roczną premią. Niestety, jeden raz, kiedy się nazywa, zwraca 404. Czy to oznacza, że nikt nie jest należny za premię, czy też aplikacja nie działa obecnie z powodu nowego wdrożenia?
-> W przypadku aplikacji, które dbają o jakość swoich danych, 404 bez encji odpowiedzi jest więc praktycznie niemożliwe.
Ponadto wiele platform klienckich odpowiada na błąd 404, zgłaszając wyjątek bez zadawania dalszych pytań. Zmusza to programistę klienta do wychwycenia tego wyjątku, do jego oceny, a następnie do podjęcia decyzji na podstawie tego, czy zapisać go jako błąd wykrywany np. Przez komponent monitorujący, czy też zignorować. To też nie wydaje mi się ładne.
Zaletą 404 nad 204 jest to, że może zwrócić encję odpowiedzi, która może zawierać pewne informacje o tym, dlaczego nie znaleziono żądanego zasobu. Ale jeśli to naprawdę jest istotne, można również rozważyć użycie odpowiedzi 200 OK i zaprojektować system w sposób, który pozwoli na reakcje na błędy w danych danych. Alternatywnie, można użyć ładunku odpowiedzi 404 do zwrócenia uporządkowanej informacji do dzwoniącego. Jeśli otrzyma np. Stronę HTML zamiast XML lub JSON, którą może przeanalizować, jest to dobry wskaźnik, że coś technicznego poszło nie tak zamiast odpowiedzi „brak wyniku”, która może być poprawna z punktu widzenia osoby dzwoniącej. Lub można do tego użyć nagłówka odpowiedzi HTTP.
Mimo to wolałbym 204 lub 200 z pustą odpowiedzią. W ten sposób status technicznego wykonania żądania jest oddzielony od logicznego wyniku żądania. 2xx oznacza „wykonanie techniczne ok, to jest wynik, radzimy sobie z tym”.
Myślę, że w większości przypadków klient powinien zdecydować, czy pusty wynik jest akceptowalny, czy nie. Zwracając 404 bez odpowiedzi, pomimo prawidłowego wykonania technicznego, klient może zdecydować o uznaniu przypadków za błędy, które po prostu nie są błędami.
Inna szybka analogia: Zwrócenie wartości 404 dla „nie znaleziono wyniku” jest jak zgłoszenie wyjątku DatabaseConnectionException, jeśli zapytanie SQL nie zwróci wyników. Może to zrobić zadanie, ale istnieje wiele możliwych przyczyn technicznych, które rzucają ten sam wyjątek, który następnie zostałby wzięty za prawidłowy wynik.
źródło
503 Service Unavailable
./users
trasę, ale/users/9
„Użytkownik znany jako # 9”), więc porównanie „pustego zestawu wyników” nie ma sensu. 404 oznacza, że obiekt nie istnieje.Na początku myślałem, że 204 ma sens, ale po dyskusjach uważam, że 404 to jedyna prawdziwa poprawna odpowiedź. Rozważ następujące dane:
Użytkownicy: John, Peter
Niektóre tło:
wyszukiwanie zwraca tablicę, po prostu nie miała żadnych dopasowań, ale ma treść: pusta tablica .
404 jest oczywiście najlepiej znany z adresów URL, które nie są obsługiwane przez żądany serwer, ale brakujący zasób jest w rzeczywistości taki sam.
Mimo że
/users/:name
jest dopasowanyusers/kyle
, użytkownik Kyle nie jest zasobem dostępnym, więc 404 nadal obowiązuje. To nie jest wyszukiwane hasło, to bezpośrednie odwołanie do dynamicznego adresu URL , więc jest 404.W każdym razie moje dwa centy :)
źródło
Jeśli oczekuje się, że zasób istnieje, ale może być pusty, argumentowałbym, że łatwiej byłoby uzyskać 200 OK z reprezentacją wskazującą, że rzecz jest pusta.
Wolę więc, żeby / rzeczy zwróciły 200 OK z {„Items”: []} niż 204 z niczym, ponieważ w ten sposób kolekcja z 0 przedmiotami może być traktowana tak samo jak kolekcja z jednym lub więcej pozycji w nim.
Zostawiłbym 204 No Content dla PUT i DELETE, gdzie może się zdarzyć, że tak naprawdę nie ma użytecznej reprezentacji.
W przypadku, gdy / thing / 9 naprawdę nie istnieje, 404 jest odpowiednie.
źródło
customers/1/addressbook
RPC, należy wywołać punkt końcowy podobnyGetCustomerAddressBook
do albo odebrać dane lub zasadniczo zerowy i nie trzeba się martwić o złożoność HTTP. Oba mają swoje zalety i wady.W poprzednich projektach korzystałem z 404. Jeśli nie ma użytkownika 9, obiekt nie został znaleziony. Dlatego 404 nie znaleziono jest właściwe.
Ponieważ obiekt istnieje, ale nie ma danych, 204 No Content byłoby odpowiednie. Myślę, że w twoim przypadku obiekt nie istnieje.
źródło
Zgodnie z postem w3 ,
Żądanie się powiodło. Informacje zwrócone z odpowiedzią zależą od metody użytej w żądaniu
Żądanie zostało zaakceptowane do przetworzenia, ale przetwarzanie nie zostało zakończone.
Serwer spełnił żądanie, ale nie musi zwracać treści encji i może chcieć zwrócić zaktualizowane metainformacje.
Serwer nie mógł zrozumieć żądania z powodu nieprawidłowej składni. Klient NIE POWINIEN powtarzać żądania bez modyfikacji
Żądanie wymaga uwierzytelnienia użytkownika. Odpowiedź MUSI zawierać pole nagłówka Uwierzytelnianie WWW
Serwer nie znalazł nic pasującego do URI żądania. Nie podano żadnych wskazówek, czy stan jest tymczasowy czy trwały
źródło
204 No Content
gdy nie znajdzie żadnych wyników. Nie404
, ma dla ciebie wynik, ale nie ma treści ..Podsumowując lub upraszczając,
2xx: Dane opcjonalne: Dobrze sformatowany identyfikator URI: Kryteria nie są częścią identyfikatora URI: Jeśli kryteria są opcjonalne, można je określić w @RequestBody, a @RequestParam powinien prowadzić do 2xx. Przykład: filtruj według nazwy / statusu
4xx: Oczekiwane dane: Niepoprawny identyfikator URI: Kryteria są częścią identyfikatora URI: Jeśli kryteria są obowiązkowe, które można określić tylko w @PathVariable, powinno to prowadzić do 4xx. Przykład: wyszukiwanie według unikalnego identyfikatora.
Tak więc dla pytanej sytuacji: „users / 9” to 4xx (prawdopodobnie 404) Ale dla „users? Name = superman” powinno być 2xx (ewentualnie 204)
źródło
Zadawane są dwa pytania. Jeden w tytule i jeden w przykładzie. Myślę, że częściowo doprowadziło to do sporu o to, która odpowiedź jest odpowiednia.
Tytuł pytania dotyczy pustych danych. Puste dane to nadal dane, ale to nie to samo, co brak danych. Sugeruje to żądanie zestawu wyników, np. Listy, być może od
/users
. Jeśli lista jest pusta, nadal jest listą, dlatego najbardziej odpowiednia jest 204 (bez zawartości). Właśnie poprosiłeś o listę użytkowników i otrzymałeś jednego, akurat nie ma treści.Podany przykład zamiast tego pyta o konkretny obiekt, użytkownika,
/users/9
. Jeśli użytkownik # 9 nie zostanie znaleziony, wówczas obiekt użytkownika nie zostanie zwrócony. Poprosiłeś o określony zasób (obiekt użytkownika) i nie dostałeś go, ponieważ nie został znaleziony, więc 404 jest odpowiednie.Myślę, że sposobem na rozwiązanie tego problemu jest użycie odpowiedzi w sposób, jakiego można się spodziewać bez dodawania instrukcji warunkowych, a następnie użycie 204, w przeciwnym razie użycie 404.
W moich przykładach mogę iterować po pustej liście bez sprawdzania, czy ma ona zawartość, ale nie mogę wyświetlić danych obiektu użytkownika na obiekcie zerowym bez zerwania czegoś lub dodania zaznaczenia, aby sprawdzić, czy jest on pusty.
Możesz oczywiście zwrócić obiekt przy użyciu wzorca zerowego, jeśli odpowiada to Twoim potrzebom, ale jest to dyskusja na inny wątek.
źródło
Po zastanowieniu się nie powinieneś używać
404
dlaczego?W oparciu o RFC 7231 poprawny kod stanu to
204
W powyższych odpowiedziach zauważyłem 1 małe nieporozumienie:
1. - zasobem jest:
/users
2.
/users/8
- nie jest zasobem, to jest: zasób/users
z parametrem route8
, być może konsument nie może go zauważyć i nie zna różnicy, ale wydawca wie i musi to wiedzieć! ... więc musi zwrócić dokładną odpowiedź konsumentom. Kropka.więc:
W oparciu o RFC: 404 jest niepoprawny, ponieważ zasoby
/users
zostały znalezione, ale logika wykonana przy użyciu parametru8
nie znalazła żadnegocontent
do zwrócenia jako odpowiedzi, więc poprawna odpowiedź to:204
Główny punkt tutaj:
404
nie znaleziono nawet zasobu do przetworzenia wewnętrznej logiki204
to: znalazłem zasób, logika została wykonana, ale nie znalazłem żadnych danych przy użyciu kryteriów podanych w parametrze route, więc nie mogę ci nic zwrócić. Przepraszam, sprawdź swoje kryteria i zadzwoń ponownie.200
: ok znalazłem zasób, logika została wykonana (nawet jeśli nie jestem zmuszony do niczego zwracać) weź to i użyj go do woli.205
: (najlepsza opcja odpowiedzi GET) Znalazłem zasób, logika została wykonana, mam dla ciebie trochę treści, używaj jej dobrze, o tak przy okazji, jeśli zamierzasz udostępnić to w widoku, odśwież widok, aby pokaż to.Mam nadzieję, że to pomoże.
źródło
Istniejące odpowiedzi nie wyjaśniają, że ma to znaczenie, czy używasz parametrów ścieżki, czy parametrów zapytania.
/users/9
odpowiedzi należy odpowiedzieć,404
ponieważ nie znaleziono tego zasobu./users/9
jest zasobem, a wynik jest jednoznaczny lub błąd, nie istnieje. To nie jest monada./users?id=9
odpowiedzi należy odpowiedzieć,204
ponieważ zasób/users
został znaleziony, ale nie mógł zwrócić żadnych danych. Zasób/users
istnieje, a wynik jest n-ary, istnieje nawet, jeśli jest pusty. Jeśliid
jest unikalny, jest to monada.To, czy użyć parametrów ścieżki, czy parametrów zapytania, zależy od przypadku użycia. Preferuję parametry ścieżki dla argumentów obowiązkowych, normatywnych lub identyfikujących oraz parametry zapytań dla argumentów opcjonalnych, nienormatywnych lub przypisujących (takich jak stronicowanie, ustawienia regionalne sortowania i inne). W REST API, użyłbym
/users/9
nie/users?id=9
przede wszystkim ze względu na możliwość zagnieżdżenia się dostać „rekordów dziecko” jak/users/9/ssh-keys/0
zdobyć pierwszy klucz publiczny lub ssh/users/9/address/2
, aby uzyskać trzeci adres pocztowy.Wolę używać 404. Oto dlaczego:
204
jest jakvoid
metoda. Nie chciałbym używać go doGET
tylko dlaPOST
,PUT
iDELETE
. Robię wyjątek w przypadku,GET
gdy identyfikatorami są parametry zapytania, a nie parametry ścieżki.NoSuchElementException
,ArrayIndexOutOfBoundsException
lub coś w tym rodzaju, spowodowane przez klienta przy użyciu identyfikatora, który nie istnieje, tak, to jest to błąd klienta.204
oznacza dodatkową gałąź w kodzie, której można by uniknąć. Komplikuje kod klienta, aw niektórych przypadkach również komplikuje kod serwera (w zależności od tego, czy używasz encji / modeli monad, czy zwykłych encji / modeli; zdecydowanie zalecam unikanie monod encji / modelu, może to prowadzić do nieprzyjemnych błędów, ponieważ ponieważ monady, którą uważasz, że operacja się powiodła i zwróć 200 lub 204, gdy powinieneś zwrócić coś innego).Last but not least: spójność
GET /users/9
PUT /users/9
iDELETE /users/9
PUT /users/9
iDELETE /users/9
już trzeba wrócić204
w przypadku udanej aktualizacji lub usunięcia. Co więc powinni zwrócić, gdyby użytkownik 9 nie istniał? Nie ma sensu przedstawiać tej samej sytuacji jako różnych kodów stanu w zależności od zastosowanej metody HTTP.Poza tym nie jest to normatywny, ale kulturowy powód: jeśli
204
zostanie użyte wGET /users/9
następnej rzeczy, co wydarzy się w projekcie, to to, że ktoś myśli, że powrót204
jest dobry dla metod n-ary. A to komplikuje kod klienta, ponieważ zamiast po prostu sprawdzać,2xx
a następnie dekodować ciało, klient musi teraz konkretnie sprawdzić204
i w tym przypadku pominąć dekodowanie ciała. Bud, co zamiast tego robi klient? Utworzyć pustą tablicę? Dlaczego więc nie mieć tego na kablu? Jeśli klient tworzy pustą tablicę, 204 jest formą głupiej kompresji. Jeśli klient używanull
zamiast tego, otwiera się zupełnie inna puszka robaków.źródło
Twitter używa 404 z niestandardowym komunikatem o błędzie, takim jak „Nie znaleziono danych”.
Patrz: https://developer.twitter.com/en/docs/basics/response-codes.html
źródło
204 jest bardziej odpowiednie. Zwłaszcza, gdy masz system alertów, który zapewnia bezpieczeństwo Twojej witryny, 404 w tym przypadku spowodowałoby zamieszanie, ponieważ nie wiesz, że niektóre alarmy 404 to błędy zaplecza lub normalne żądania, ale odpowiedź jest pusta.
źródło
Powiedziałbym, że żadne z nich nie jest właściwe. Jak powiedziano - np. Przez @anneb, również uważam, że część problemów wynika z używania kodu odpowiedzi HTTP do transportu statusu związanego z usługą RESTful. Wszystko, co usługa REST ma do powiedzenia na temat własnego przetwarzania, powinno być transportowane za pomocą kodów specyficznych dla REST.
1
Twierdzę, że jeśli serwer HTTP znajdzie jakąkolwiek usługę, która jest gotowa odpowiedzieć na żądanie, które zostało wysłane, nie powinien odpowiedzieć HTTP 404 - w końcu coś zostało znalezione przez serwer - chyba że zostało to wyraźnie określone przez usługa przetwarzająca żądanie.
Załóżmy na chwilę następujący adres:
http://example.com/service/return/test
.404
jest poprawny. To samo jest prawdą, jeśli prosi jakąś usługę o dostarczenie dokładnie tego pliku, a ta usługa mówi mu, że nic o tej nazwie nie istnieje.Bez odpowiedzi ze strony usługi wyraźnie wymagającej innego zachowania serwer HTTP może powiedzieć tylko 3 rzeczy:
503
jeśli usługa, która ma obsłużyć żądanie, nie działa lub nie odpowiada;200
w przeciwnym razie serwer HTTP może faktycznie spełnić żądanie - bez względu na to, co powie później usługa;400
lub404
wskazać, że nie ma takiej usługi (w przeciwieństwie do „istnieje, ale offline”) i nic innego nie znaleziono.2)
Wracając do pytania: Myślę, że najczystszym podejściem byłoby w ogóle nie używać kodu odpowiedzi HTTP innego niż wspomniany wcześniej. Jeśli usługa jest obecna i odpowiada, kod HTTP powinien wynosić 200. Odpowiedź powinna zawierać status, który usługa zwróciła w osobnym nagłówku - tutaj usługa może powiedzieć
REST:EMPTY
np. jeśli został poproszony o wyszukanie czegoś i że badania wróciły puste;REST:NOT FOUND
gdyby został poproszony o coś. „Podobny do identyfikatora” - może to być nazwa pliku lub zasób według identyfikatora lub pozycji nr 24 itd. - i że nie znaleziono określonego zasobu (zwykle żądano jednego zasobu i nie znaleziono go);REST:INVALID
jeśli jakakolwiek część żądania, które zostało wysłane, nie jest rozpoznawana przez usługę.(zwróć uwagę, że poprzedziłem je słowem „REST:”, aby zaznaczyć fakt, że chociaż mogą mieć te same wartości lub sformułowania, co kody odpowiedzi HTTP, są zupełnie inne)
3)
Wróćmy do powyższego adresu URL i sprawdźmy przypadek B, w którym usługa wskazuje serwerowi HTTP, że sam nie obsługuje tego żądania, ale przekazuje je
SERVICE
. HTTP podaje tylko to, co zostało przekazaneSERVICE
, nie wie nic o tejreturn/test
części, ponieważ jest to przedmiotem handluSERVICE
. Jeśli ta usługa jest uruchomiona, HTTP powinien powrócić,200
ponieważ rzeczywiście znalazł coś do obsługi żądania.Status zwracany przez
SERVICE
(i który, jak wspomniano powyżej, chciałby zobaczyć w osobnym nagłówku), zależy od tego, czego się faktycznie oczekuje:return/test
poprosi o określony zasób: jeśli istnieje, zwróć go ze statusemREST:FOUND
; jeśli ten zasób nie istnieje, zwróćREST:NOT FOUND
; można to rozszerzyć na zwrot,REST:GONE
jeśli wiemy, że kiedyś istniał i nie wróci, aREST:MOVED
jeśli wiemy, że zniknął z Hollywoodreturn/test
jest uważany za operację wyszukiwania lub filtrowania: jeśli zestaw wyników jest pusty, zwróć pusty zestaw żądanego typu i statusREST:EMPTY
; zestaw wyników w żądanym typie i statusREST:SUCCESS
return/test
nie jest operacją rozpoznawaną przezSERVICE
: zwróć,REST:ERROR
jeśli jest całkowicie niepoprawna (np. literówkaretrun/test
), lubREST:NOT IMPLEMENTED
jeśli jest planowana na później.4
To rozróżnienie jest o wiele czystsze niż mieszanie dwóch różnych rzeczy. Ułatwi to także debugowanie, a przetwarzanie będzie nieco bardziej skomplikowane, jeśli w ogóle.
Podsumowanie
Problem i dyskusja wynikają z faktu, że kody odpowiedzi HTTP są używane do oznaczenia stanu usługi, której wyniki są obsługiwane przez HTTP, lub do oznaczenia czegoś. nie wchodzi to w zakres samego serwera HTTP. Z powodu tej rozbieżności na pytanie nie można odpowiedzieć, a wszystkie opinie są przedmiotem wielu dyskusji.
Stan żądania przetworzonego przez usługę, a nie serwer HTTP NAPRAWDĘ NIE POWINIEN (RFC 6919) podawany przez kod odpowiedzi HTTP. Kod HTTP POWINIEN (RFC 2119) zawiera tylko informacje, które serwer HTTP może podać ze swojego zakresu: mianowicie, czy stwierdzono, że usługa przetworzyła żądanie, czy nie.
Zamiast tego NALEŻY zastosować inny sposób poinformowania konsumenta o stanie zapytania do usługi, która faktycznie przetwarza żądanie. Moja propozycja polega na tym, aby zrobić to za pomocą określonego nagłówka. Idealnie zarówno nazwa nagłówka, jak i jego treść są zgodne ze standardem, który ułatwia konsumentom pracę z tymi odpowiedziami.
źródło
Zgodnie z RFC7231 - strona59 ( https://tools.ietf.org/html/rfc7231#page-59 ) definicja odpowiedzi kodu stanu 404 to:
6.5.4 404 Not Found Kod stanu 404 (Not Found) wskazuje, że serwer źródłowy nie znalazł bieżącej reprezentacji zasobu docelowego lub nie chce ujawnić, że istnieje. Kod statusu 404 nie wskazuje, czy ten brak reprezentacji jest tymczasowy czy trwały; kod statusu 410 (Brak) jest preferowany w stosunku do 404, jeżeli serwer źródłowy wie, prawdopodobnie za pomocą pewnych konfigurowalnych środków, że stan prawdopodobnie będzie trwały. Odpowiedź 404 jest domyślnie buforowana; tzn. o ile nie wskazano inaczej w definicji metody lub jawnych kontrolkach pamięci podręcznej (patrz sekcja 4.2.2 [RFC7234]).
A najważniejszą rzeczą, która budzi wątpliwości, jest definicja zasobu w powyższym kontekście. Zgodnie z tą samą RFC (7231) definicja zasobu to:
Zasoby: Obiekt docelowy żądania HTTP nazywa się „zasobem”. HTTP nie ogranicza charakteru zasobu; definiuje jedynie interfejs, który można wykorzystać do interakcji z zasobami. Każdy zasób jest identyfikowany przez jednolity identyfikator zasobu (URI), jak opisano w sekcji 2.7 [RFC7230]. Gdy klient konstruuje komunikat żądania HTTP / 1.1, wysyła docelowy identyfikator URI w jednej z różnych form, jak zdefiniowano w (Sekcja 5.3 [RFC7230]). Po otrzymaniu żądania serwer rekonstruuje efektywny identyfikator URI żądania dla zasobu docelowego (sekcja 5.5 [RFC7230]). Jednym z celów projektowych HTTP jest oddzielenie identyfikacji zasobów od semantyki żądań, co jest możliwe dzięki przypisaniu semantyki żądaniom do metody żądania (sekcja 4) i kilku pól nagłówka modyfikujących żądanie (sekcja 5).
W moim rozumieniu kod stanu 404 nie powinien być używany w przypadku pomyślnego żądania GET z pustym wynikiem. (Przykład: lista bez wyniku dla konkretnego filtra)
źródło
Takie rzeczy mogą być subiektywne, a po obu stronach jest kilka interesujących i różnych solidnych argumentów. Jednak [moim zdaniem] zwrot 404 za brakujące dane jest nieprawidłowy . Oto uproszczony opis, aby to wyjaśnić:
Nic się nie zepsuło, punkt końcowy został znaleziony, a tabela i kolumny zostały znalezione, więc baza danych zapytała, a dane „pomyślnie” zwróciły!
Teraz - czy ta „udana odpowiedź” zawiera dane, czy nie ma znaczenia, poprosiłeś o odpowiedź „potencjalnych” danych i ta odpowiedź z „potencjalnymi” danymi została spełniona. Puste, puste itp. Są poprawnymi danymi.
200 oznacza po prostu, że każde żądanie, które zrobiliśmy, zakończyło się powodzeniem. Żądam danych, nic nie poszło nie tak z HTTP / REST, a ponieważ dane (choć puste) zostały zwrócone, moje „żądanie danych” zakończyło się powodzeniem.
Zwróć 200 i pozwól, aby osoba żądająca obsługiwała puste dane, ponieważ uzasadnia to każdy scenariusz!
Rozważ ten przykład:
Te puste dane są całkowicie poprawne. Oznacza to, że użytkownik nie ma wykroczeń. Jest to 200, ponieważ wszystko jest ważne, ponieważ wtedy mogę zrobić:
Jeśli uważasz, że to 404, co mówisz? Nie można znaleźć wykroczeń użytkownika? Otóż gramatycznie jest to poprawne, ale w świecie REST nie jest poprawne, jeśli sukces lub porażka dotyczy żądania. Dane „wykroczenia” dla tego użytkownika można znaleźć pomyślnie, jest zero wykroczeń - liczba rzeczywista reprezentuje prawidłowy stan.
[Bezczelna uwaga ..]
W swoim tytule podświadomie zgadzasz się, że 200 to poprawna odpowiedź:
Oto kilka rzeczy, które należy wziąć pod uwagę przy wyborze kodu stanu, którego należy użyć, niezależnie od podmiotowości i trudnych wyborów:
źródło
Zakoduj treść odpowiedzi za pomocą wspólnego wyliczenia, które pozwala klientowi ją włączyć i odpowiednio rozwidlić logikę. Nie jestem pewien, jak twój klient rozróżniłby różnicę między „404 nie znaleziono danych” a „404 nie znaleziono zasobu”? Nie chcesz, aby ktoś przeglądał użytkownika Z / 9 i kazał klientowi zastanawiać się, jakby żądanie było prawidłowe, ale nie zwrócono żadnych danych.
źródło
Dlaczego nie użyć 410? Sugeruje to, że żądany zasób już nie istnieje i oczekuje się, że klient nigdy nie poprosi o ten zasób, w twoim przypadku
users/9
.Więcej informacji na temat 410 można znaleźć tutaj: https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
źródło
To smutne, że coś tak prostego i dobrze zdefiniowanego stało się „oparte na opiniach” w tym wątku.
Serwer HTTP zna tylko „encje”, które są abstrakcją dla dowolnej treści, czy to statyczna strona internetowa, lista wyników wyszukiwania, lista innych encji, opis czegoś, plik multimedialny itp.
Oczekuje się, że każdy taki podmiot będzie można zidentyfikować za pomocą unikalnego adresu URL, np
Jeśli serwer znajdzie zasób pod danym adresem URL, nie ma znaczenia, jaka jest jego zawartość - 2G danych, null, {}, [] - tak długo, jak istnieje, będzie to 200. Ale jeśli taka jednostka jest serwer nie jest znany, oczekuje się, że zwróci 404 „Nie znaleziono”.
Jedno zamieszanie wydaje się pochodzić od programistów, którzy uważają, że jeśli aplikacja ma moduł obsługi dla określonego kształtu ścieżki, nie powinien to być błąd. W oczach protokołu HTTP nie ma znaczenia, co wydarzyło się we wnętrzu serwera (tj. Czy router domyślny zareagował, czy moduł obsługi określonego kształtu ścieżki), o ile na serwerze nie ma pasującego obiektu żądany adres URL (żądany plik MP3, strona internetowa, obiekt użytkownika itp.), który zwróciłby prawidłową treść (pustą lub inną), musi to być 404 (lub 410 itd.).
Kolejnym punktem zamieszania wydaje się być „brak danych” i „brak bytu”. Pierwsza dotyczy zawartości bytu, a druga jego istnienia.
Przykład 1:
Przykład 2:
Przykład 3:
źródło
404 byłoby bardzo mylące dla każdego klienta, jeśli wrócisz tylko dlatego, że nie ma danych w odpowiedzi.
Dla mnie kod odpowiedzi 200 z pustym ciałem wystarczy, aby zrozumieć, że wszystko jest idealne, ale nie ma danych spełniających wymagania.
źródło
Według Microsoft: Typy akcji kontrolera zwracane w interfejsie API ASP.NET Core , przewiń w dół prawie do dołu, znajdziesz następujący komunikat o 404 odnoszący się do obiektu nie znalezionego w bazie danych. Tutaj sugerują, że 404 jest odpowiedni dla pustych danych.
źródło
Jak wielu twierdzi, 404 wprowadza w błąd i nie pozwala klientowi na rozróżnienie, jeśli identyfikator URI żądania nie istnieje lub jeśli żądany URI nie może pobrać żądanego zasobu.
Oczekuje się, że status 200 będzie zawierać dane zasobów - więc nie jest to właściwy wybór. Status 204 oznacza coś zupełnie innego i nie powinien być wykorzystywany jako odpowiedź na żądania GET.
Wszystkie pozostałe istniejące statusy nie mają zastosowania z tego czy innego powodu.
Widziałem ten temat w kółko w wielu miejscach. Dla mnie boleśnie oczywiste jest, że aby wyeliminować zamieszanie wokół tematu, potrzebny jest dedykowany status sukcesu. Coś w rodzaju „ 209 - Brak zasobu do wyświetlenia”.
Będzie to status 2xx, ponieważ nie znalezienie identyfikatora nie powinno być uważane za błąd klienta (gdyby klienci wiedzieli wszystko, co znajduje się w bazie danych serwera, nie musieliby o nic pytać serwera, prawda?). Ten dedykowany status rozwiązuje wszystkie problemy omawiane przy użyciu innych statusów.
Jedyne pytanie brzmi: jak sprawić, by RFC zaakceptował to jako standard?
źródło