Jaki jest właściwy kod odpowiedzi REST dla poprawnego żądania, ale pustych danych?

Na przykład uruchamiasz żądanie GET dla users/9, ale nie ma Użytkownika o id # 9. Jaki jest najlepszy kod odpowiedzi?

  • 200 OK
  • 202]}
  • 204 Brak Treści
  • 400 Bad Request
  • 404 Nie Znaleziono
Author: Machavity, 2012-07-31

12 answers

TL; DR: użyj 404

Zobacz Ten Blog. To bardzo dobrze wyjaśnia.

Podsumowanie komentarzy na blogu 204:

  1. {[2] } nie jest zbyt przydatny jako kod odpowiedzi dla przeglądarki (chociaż zgodnie ze specyfikacją HTTP przeglądarki muszą rozumieć go jako kod odpowiedzi "nie zmieniaj widoku").
  2. 204 No Content jest jednak bardzo przydatne dla usług internetowych ajax, które mogą chcieć wskazać sukces bez konieczności zwracania czegoś. (Szczególnie w przypadkach takich jak DELETE lub POST, które nie wymagają opinii).

Odpowiedzią na twoje pytanie jest zatem użycie 404 w Twoim przypadku. 204 jest wyspecjalizowanym kodem reponse, który nie powinien często powracać do przeglądarki w odpowiedzi na GET.

Inne kody odpowiedzi, które są jeszcze mniej odpowiednie niż 204 i 404:

  1. 200 powinny być zwrócone z ciałem tego, co udało ci się pobrać. Nie nadaje się, gdy istota, którą jesteś pobieranie nie istnieje.
  2. 202 jest używany, gdy serwer rozpoczął pracę nad obiektem, ale obiekt nie jest jeszcze w pełni gotowy. Na pewno nie tutaj. Nie rozpocząłeś, ani nie rozpoczniesz budowy użytkownika 9 w odpowiedzi na zapytanie GET. To łamie różne zasady.
  3. 400 jest używany w odpowiedzi na źle sformatowane żądanie HTTP (na przykład źle sformatowane nagłówki http, nieprawidłowo uporządkowane segmenty itp.). To prawie na pewno będzie obsługiwane przez cokolwiek framework, którego używasz. Nie powinieneś mieć z tym do czynienia, chyba że piszesz własny serwer od podstaw. Edytuj: nowsze RFC pozwalają teraz na użycie 400 dla semantycznie nieprawidłowych żądań.
Szczególnie pomocny jest Opis Wikipedii kodów statusu HTTP. Możesz również zobaczyć definicje w dokumencie HTTP / 1.1 RFC2616 pod adresem www.w3.org
 154
Author: Crisfole,
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-11 17:32:25

Zdecydowanie sprzeciwiam się 404 na rzecz 204 lub 200 z pustymi danymi.

Żądanie zostało odebrane i poprawnie przetworzone - wywołało kod aplikacji na serwerze, więc nie można powiedzieć, że był to błąd klienta, a więc cała klasa kodów błędów klienta (4xx) nie pasuje.

Co ważniejsze, 404 może się zdarzyć z wielu powodów technicznych. Np. tymczasowo dezaktywowana lub odinstalowana aplikacja na serwerze, problemy z połączeniem proxy i takie tam. Dlatego klient nie może rozróżnić 404, który oznacza "pusty zestaw wyników" i 404, który oznacza "usługa nie może zostać znaleziona, spróbuj ponownie później".

Może to być fatalne: wyobraź sobie usługę księgową w Twojej firmie, która wymienia wszystkich pracowników, których należy się roczna premia. Niestety, ten jeden raz, kiedy jest nazywany, zwraca 404. Czy to oznacza, że nikt nie jest zobowiązany do otrzymania bonusu lub że aplikacja jest obecnie niedostępna do nowego wdrożenia?

- > dla aplikacji które dbają o jakość swoich danych, dlatego 404 jest praktycznie nie do przejścia.

Ponadto wiele ram klienckich reaguje na 404, rzucając wyjątek bez zadawania dalszych pytań. Zmusza to programistę klienta do wychwycenia tego wyjątku, oceny go, a następnie podjęcia na jego podstawie decyzji, czy zapisać go jako błąd wychwycony np. przez komponent monitorujący, czy też zignorować. To też nie wydaje mi się ładne.

Jedyną przewagą 404 nad 204 jest że może zwrócić jednostkę odpowiedzi, która może zawierać pewne informacje o tym, dlaczego żądany zasób nie został znaleziony. Ale jeśli to naprawdę jest istotne, można również rozważyć użycie odpowiedzi OK 200 i zaprojektować system w sposób, który pozwala na odpowiedzi na błędy w danych ładunku. Alternatywnie, można użyć ładunku odpowiedzi 404, aby zwrócić ustrukturyzowane informacje do dzwoniącego. Jeśli otrzyma np. stronę html zamiast XML lub JSON, którą może przeanalizować, to jest to dobre wskaźnik, że coś poszło nie tak z technicznego punktu widzenia zamiast odpowiedzi "Brak wyniku", która może być ważna z punktu widzenia rozmówcy. Można też użyć do tego 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, poradź sobie z tym".

Myślę, że w większości przypadków powinno być pozostawione do klient decyduje, czy pusty wynik jest akceptowalny, czy nie. Zwracając 404 pomimo poprawnego wykonania technicznego klient może zdecydować się uznać przypadki za błędy, które po prostu nie są błędami.

Kolejna analogia: zwracanie 404 dla "no result found" jest jak rzucanie DatabaseConnectionException, jeśli zapytanie SQL nie zwróciło żadnych wyników. Może wykonać zadanie, ale istnieje wiele możliwych przyczyn technicznych, które rzucają ten sam wyjątek, który następnie byłby mylony z ważnym wynik.

 211
Author: Jens Wurm,
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-17 10:29:19

Jeśli oczekuje się, że zasób istnieje, ale może być pusty, argumentowałbym, że łatwiej będzie uzyskać 200 OK z reprezentacją, która wskazuje, że rzecz jest pusta.

Więc wolałbym, aby /rzeczy zwracały 200 OK z {"Items": []} niż 204 bez niczego, ponieważ w ten sposób zbiór z 0 przedmiotami może być traktowany tak samo jak zbiór z jednym lub więcej przedmiotami w nim.

Zostawiłbym 204 No Content for PUTs and DELETEs, gdzie to może być tak, że naprawdę nie ma użytecznej reprezentacji.

W przypadku, gdy ta /rzecz/9 naprawdę nie istnieje, 404 jest odpowiednie.

 16
Author: j0057,
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-07-22 20:00:30

W poprzednich projektach używałem 404. Jeżeli nie ma użytkownika 9, wtedy obiekt nie został znaleziony. Dlatego 404 Nie znaleziono jest właściwe.

Dla obiekt istnieje, ale nie ma danych, 204 żadna treść nie byłaby odpowiednia. Myślę, że w Twoim przypadku obiekt nie istnieje.

 14
Author: Max,
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
2012-07-31 18:47:50

Na początku myślałem, że 204 będzie miało sens, ale po dyskusjach uważam, że 404 jest jedyną poprawną odpowiedzią. Rozważmy następujące dane:

Użytkownicy: Jan, Piotr

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:

  1. Wyszukiwanie zwraca tablicę, po prostu nie ma dopasowania, ale ma zawartość: pustą tablicę .

  2. 404 jest oczywiście najbardziej znany z adresów url, które nie są obsługiwane przez żądanym serwerze, ale brakującym zasobem jest w zasadzie to samo.
    Mimo że /users/:name jest dopasowane do users/kyle, Użytkownik Kyle nie jest dostępny, więc 404 nadal obowiązuje. To nie jest wyszukiwanie, jest to bezpośrednie odniesienie przez dynamiczny url , więc 404 jest.

W każdym razie moje dwa grosze:)

 11
Author: Justus Romijn,
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-07-30 06:32:39

Zgodnie z W3 post,

200 OK

Prośba się powiodła. Informacje zwracane w odpowiedzi zależą od metody użytej w zapytaniu

202 Accepted

Wniosek został przyjęty do przetworzenia, ale przetwarzanie nie zostało zakończone.

204 No Content

Serwer spełnił żądanie, ale nie musi zwracać entity-body i może chcieć zwrócić zaktualizowaną metainformację.

400 Bad Request

Żądanie nie może być zrozumiane przez serwer z powodu nieprawidłowej składni. Klient nie powinien powtarzać żądania bez modyfikacji

401 Nieautoryzowano

Żądanie wymaga uwierzytelnienia użytkownika. Odpowiedź musi zawierać pole nagłówka WWW-Authenticate

404 Nie Znaleziono

The serwer nie znalazł niczego pasującego do żądania-URI. Nie podano wskazania, czy warunek jest tymczasowy czy trwały

 9
Author: Dev4World,
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-28 13:21:47

Podsumowując lub upraszczając,

2xx: opcjonalne dane: dobrze uformowane URI: Criteria nie jest częścią URI: jeśli kryteria są opcjonalne, które mogą być podane w @RequestBody i @RequestParam powinny prowadzić do 2xx. przykład: Filtruj według nazwy / statusu

4XX: Expected data : Not well formed URI: Criteria jest częścią URI: jeśli kryteria są obowiązkowe, które mogą być podane tylko w @PathVariable, to powinno prowadzić do 4xx. przykład: lookup by unique id.

Tak więc dla zapytanych sytuacja: "users / 9" to 4xx (ewentualnie 404) Ale dla " użytkowników?nazwa = superman " powinno być 2xx (prawdopodobnie 204)

 8
Author: Ashish Singh,
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
2016-11-15 18:47:04

Zadano dwa pytania. Jeden w tytule i jeden w przykładzie. Myślę, że doprowadziło to częściowo do tego, jaka jest wielkość sporu w kwestii tego, która odpowiedź jest właściwa.

Tytuł pytania Pyta o puste dane. Puste dane są nadal danymi, ale nie są takie same jak brak danych. Więc to sugeruje żądanie zestawu wyników, tj. listy, być może z /users. Jeśli lista jest pusta, to nadal jest listą, dlatego 204 (Brak treści) jest najbardziej odpowiedni. Właśnie poprosiłeś o listę użytkowników i zostałeś pod warunkiem, że jeden, to po prostu nie ma treści.

Podany przykład pyta o konkretny obiekt, użytkownika, /users/9. Jeżeli użytkownik #9 nie zostanie znaleziony, wtedy nie zostanie zwrócony żaden obiekt user. Poprosiłeś o konkretny zasób (obiekt użytkownika) i nie otrzymałeś go, ponieważ nie został znaleziony, więc 404 jest odpowiednie.

Myślę, że sposób na rozwiązanie tego problemu polega na tym, że jeśli możesz użyć odpowiedzi w sposób, jakiego oczekujesz, bez dodawania jakiejkolwiek instrukcji warunkowej, to użyj 204, w przeciwnym razie użyj 404.

W moich przykładach mogę iterować nad pustą listą bez sprawdzania, czy ma zawartość, ale nie mogę wyświetlić danych obiektu użytkownika na obiekcie null bez łamania czegoś lub dodawania sprawdzania, czy jest null.

Możesz oczywiście zwrócić obiekt używając wzorca obiektu null, jeśli odpowiada to twoim potrzebom, ale jest to dyskusja dla innego wątku.

 5
Author: Bluebox,
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-01 16:37:03

204 jest bardziej odpowiedni. Zwłaszcza, gdy masz system alertów, aby zapewnić bezpieczeństwo witryny, 404 w tym przypadku spowodowałoby zamieszanie, ponieważ nie wiesz, że niektóre alerty 404 są błędami zaplecza lub normalnymi żądaniami, ale odpowiedź jest pusta.

 2
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
2018-01-10 02:59:59

Powiedziałbym, że żadne z nich nie jest właściwe. Jak już zostało powiedziane-np. przez @anneb, ja też uważam, że część problemów wynika z użycia kodu odpowiedzi HTTP do transportu statusu odnoszącego się do usługi RESTful. Wszystko, co usługa REST ma do powiedzenia na temat własnego przetwarzania, powinno być transportowane za pomocą specjalnych kodów REST.

1

Argumentowałbym, że jeśli serwer HTTP znajdzie jakąkolwiek usługę, która jest gotowa odpowiedzieć na wysłane żądanie, nie powinien odpowiadać za pomocą HTTP 404 – W końcu, coś zostało znalezione przez serwer-chyba że wyraźnie powiedział tak serwis, który przetwarza żądanie.

Przyjmijmy przez chwilę następujący URL: http://example.com/service/return/test.

  • Przypadek A polega na tym, że serwer "po prostu szuka pliku w systemie plików". Jeśli nie występuje, 404 jest poprawne. To samo jest prawdą, jeśli poprosi jakiś serwis o dostarczenie dokładnie tego pliku, a ten serwis powie mu, że nic o tej nazwie nie istnieje.
  • W przypadku B, serwer nie działa z "prawdziwymi" plikami, ale w rzeczywistości żądanie jest przetwarzane przez jakąś inną usługę – np. jakiś system szablonów. Tutaj serwer nie może wysuwać żadnych roszczeń co do istnienia zasobu, ponieważ nic o nim nie wie (chyba że poinformuje o tym serwis, który go obsługuje).
Serwer HTTP może powiedzieć tylko 3 rzeczy, bez żadnej odpowiedzi ze strony serwisu wyraźnie wymagającej innego zachowania.]}
  • 503 Jeśli usługa, która ma obsługiwać wniosek nie działa ani nie odpowiada;
  • W przeciwnym razie serwer HTTP może faktycznie zaspokoić żądanie – bez względu na to, co usługa powie później; [38]}
  • 400 lub 404, aby wskazać, że nie ma takiej usługi (w przeciwieństwie do "istnieje, ale offline") i nic więcej nie zostało znalezione.

2

Wracając do pytania: myślę, że najczystszym podejściem byłoby nie używać HTTP żadnego kodu odpowiedzi w ogóle inne niż powiedział wcześniej. Jeśli usługa jest obecny i odpowiadający, kod HTTP powinien wynosić 200. Odpowiedź powinna zawierać status zwrócony przez usługę w oddzielnym nagłówku-tutaj usługa może powiedzieć

  • REST:EMPTY np. jeśli poproszono go o wyszukanie sth. i że badania wróciły puste; {]}
  • REST:NOT FOUND gdyby został poproszony specjalnie o sth. "ID-like – - być to nazwa pliku lub zasobu przez ID lub wpis nr 24, itp. - i ten konkretny zasób nie został znaleziony (zazwyczaj żądano jednego konkretnego zasobu, a nie znalezione);
  • REST:INVALID Jeśli jakakolwiek część żądania została wysłana nie jest rozpoznawana przez serwis.

(zauważ, że celowo dodałem do nich prefiks "REST:", aby zaznaczyć, że chociaż mogą one mieć te same wartości lub sformułowania, co kody odpowiedzi HTTP, to są sth. zupełnie inny)

3

Wróćmy do powyższego adresu URL i sprawdźmy przypadek B, gdzie service wskazuje serwerowi HTTP, że sam nie obsługuje tego żądania, ale przekazuje je dalej do SERVICE. HTTP serwuje tylko to, co przekazuje SERVICE, nie wie nic o return/test, ponieważ jest to obsługiwane przez SERVICE. Jeśli ta usługa jest uruchomiona, HTTP powinien zwró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 oddzielnym nagłówku) zależy od tego, jakiej akcji rzeczywiście oczekuje:

  • jeśli return/test prosi o konkretny zasób: jeśli istnieje, jeśli zasoby nie istnieją, return REST:NOT FOUND; może to zostać rozszerzone na return REST:GONE jeśli wiemy, że kiedyś istniały i nie powrócą, i REST:MOVED jeśli wiemy, że odeszły do hollywood
  • jeśli {[11] } jest uważana za operację wyszukiwania lub podobną do filtra: jeśli zestaw wyników jest pusty, zwróć pusty zestaw w żądanym typie i status REST:EMPTY; zestaw wyników w żądanym typie i status REST:SUCCESS
  • jeśli return/test nie jest operacją rozpoznaną przez SERVICE: return REST:ERROR jeśli jest całkowicie błędna (np. literówka jak retrun/test), lub REST:NOT IMPLEMENTED W przypadku, gdy planowana jest na później.

4

To rozróżnienie jest o wiele czystsze niż mieszanie dwóch różnych rzeczy. Ułatwi to również debugowanie i przetwarzanie tylko nieco bardziej złożone, jeśli w ogóle.

  • jeśli zwracany jest HTTP 404, serwer mówi mi: "nie mam pojęcia o czym mówisz". Podczas gdy reszta mojej prośby może być perectly OK, jestem Szukam par ' Macha w niewłaściwych miejscach.
  • Z drugiej strony, HTTP 200 I REST: ERR mówi mi, że dostałem usługę, ale zrobiłem coś złego w moim wniosku do serwisu.
  • From HTTP 200 and REST: EMPTY, wiem, że nie zrobiłem nic złego-właściwy serwer, serwer znalazł usługę, właściwe żądanie do usługi – ale wynik wyszukiwania jest pusty.

Podsumowanie

Problem i dyskusja wynika z faktu, że kody odpowiedzi HTTP są używane do oznacza stan usługi, której wyniki są obsługiwane przez HTTP, lub oznacza sth. to nie wchodzi 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 przetwarzanego przez usługę, a nie serwer HTTP naprawdę nie powinien (RFC 6919) być podany przez kod odpowiedzi HTTP. Kod HTTP powinien (RFC 2119) zawierać tylko informacje, które serwer HTTP może podać z własnego zakresu: mianowicie, czy usługa została uznana za rozpatrującą wniosek, czy też nie.

Zamiast tego należy użyć innego sposobu, aby poinformować konsumenta o stanie żądania do usługi, która faktycznie przetwarza żądanie. Moja propozycja to zrobić za pomocą konkretnego nagłówka. Idealnie, zarówno nazwa nagłówka, jak i jego zawartość są zgodne ze standardem, który ułatwia konsumentom pracę z odpowiedziami.

 1
Author: dariok,
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-15 15:56:49

Zakoduj zawartość odpowiedzi za pomocą wspólnego enum, które pozwala klientowi na jej włączenie i odpowiednio rozwidlenie logiki. Nie jestem pewien, jak twój Klient odróżniłby różnicę między" data not found "404 a" web resource not found " 404? Nie chcesz, aby ktoś przeszukiwał Stronę Użytkownikaz/9 i sprawiał, że klient zastanawiał się, jakby żądanie było poprawne, ale nie zwrócono żadnych danych.

 0
Author: ComeIn,
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
2016-07-25 16:23:35

Dlaczego nie użyć 410? Sugeruje, że żądany zasób już nie istnieje i oczekuje się, że klient nigdy nie złoży wniosku o ten zasób, w Twoim przypadku users/9.

Więcej informacji o 410 znajdziesz tutaj: https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html

 -1
Author: Akshat Shah,
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
2016-11-30 03:58:17