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
Na przykład uruchamiasz żądanie GET, users/9
ale nie ma użytkownika o identyfikatorze nr 9. Jaki jest najlepszy kod odpowiedzi?
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 jak DELETE
lub POST
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
i 404
:
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 na GET
żą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
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.
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
METHOD URL STATUS RESPONSE
GET /users 200 [John, Peter]
GET /users/john 200 John
GET /users/kyle 404 Not found
GET /users?name=kyle` 200 []
DELETE /users/john 204 No Content
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 dopasowany users/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 :)
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.
customers/1/addressbook
RPC, należy wywołać punkt końcowy podobny GetCustomerAddressBook
do albo odebrać dane lub zasadniczo zerowy i nie trzeba się martwić o złożoność HTTP. Oba mają swoje zalety i wady.
Zgodnie z postem w3 ,
200 OK
Żądanie się powiodło. Informacje zwrócone z odpowiedzią zależą od metody użytej w żądaniu
202 Zaakceptowano
Żądanie zostało zaakceptowane do przetworzenia, ale przetwarzanie nie zostało zakończone.
204 Brak treści
Serwer spełnił żądanie, ale nie musi zwracać treści encji i może chcieć zwrócić zaktualizowane metainformacje.
400 złych wniosków
Serwer nie mógł zrozumieć żądania z powodu nieprawidłowej składni. Klient NIE POWINIEN powtarzać żądania bez modyfikacji
401 Nieautoryzowane
Żądanie wymaga uwierzytelnienia użytkownika. Odpowiedź MUSI zawierać pole nagłówka Uwierzytelnianie WWW
404 Nie Znaleziono
Serwer nie znalazł nic pasującego do URI żądania. Nie podano żadnych wskazówek, czy stan jest tymczasowy czy trwały
204 No Content
gdy nie znajdzie żadnych wyników. Nie 404
, 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)
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.
Po zastanowieniu się nie powinieneś używać 404
dlaczego?
W oparciu o RFC 7231 poprawny kod stanu to204
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 parametru 8
nie znalazła żadnego content
do zwrócenia jako odpowiedzi, więc poprawna odpowiedź to:204
Główny punkt tutaj: 404
nie znaleziono nawet zasobu do przetworzenia wewnętrznej logiki
204
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.
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śli id
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 jak void
metoda. Nie chciałbym używać go do GET
tylko dla POST
, PUT
i DELETE
. 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
i DELETE /users/9
PUT /users/9
i DELETE /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 w GET /users/9
następnej rzeczy, co wydarzy się w projekcie, to to, że ktoś myśli, że powrót 204
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żywa null
zamiast tego, otwiera się zupełnie inna puszka robaków.
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
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.
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.
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
lub 404
wskazać, że nie ma takiej usługi (w przeciwieństwie do „istnieje, ale offline”) i nic innego nie znaleziono.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)
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 przekazane SERVICE
, nie wie nic o tej return/test
części, ponieważ jest to przedmiotem handlu SERVICE
. 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 statusem REST: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, a REST: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 status REST:EMPTY
; zestaw wyników w żądanym typie i statusREST:SUCCESS
return/test
nie jest operacją rozpoznawaną przez SERVICE
: zwróć, REST:ERROR
jeśli jest całkowicie niepoprawna (np. literówka retrun/test
), lub REST:NOT IMPLEMENTED
jeśli jest planowana na później.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.
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.
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)
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ć:
Nie masz żadnych wykroczeń, jedz muffinkę jagodową!
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ź:
Jaki jest prawidłowy kod odpowiedzi REST dla prawidłowego żądania, ale puste dane?
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:
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.
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
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:
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.
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.
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?