Prawidłowa odpowiedź REST dla pustej tabeli?

106

Powiedzmy, że chcesz uzyskać listę użytkowników, dzwoniąc GETdo api/users, ale obecnie tabela została obcięta, więc nie ma żadnych użytkowników. Jaka jest właściwa odpowiedź w tym scenariuszu: 404lub 204?

IMB
źródło
19
Odpowiedziałbym 200 i pustą kolekcją (nie pustą
treścią
4
404 w tym kontekście prawdopodobnie lepiej pasowałoby do „nie znaleziono tabeli”. Powiedziałbym, że zwróć pustą listę.
mata
2
@EJoshuaS To nie jest. Oba pytania są moje i bardzo stare. Są podobne, ale nie są duplikatami.
IMB
1
@EJoshuaS Oczywiście nie są duplikatami. To pytanie dotyczy /api/userstego, kiedy to dotyczy /api/users/1.
Franklin Yu

Odpowiedzi:

230

Nie powiedziałbym.

Dlaczego nie 404 (nie znaleziono)?

Kod stanu 404 powinien być zarezerwowany dla sytuacji, w których nie można znaleźć zasobu. W tym przypadku Twoim zasobem jest kolekcja użytkowników . Ta kolekcja istnieje, ale jest obecnie pusta. Osobiście byłbym bardzo zdezorientowany jako autor klienta dla twojej aplikacji, gdybym dostał 200jeden dzień i 404następny tylko dlatego, że ktoś zdarzyło się usunąć kilku użytkowników. Co powinienem zrobić? Czy mój adres URL jest nieprawidłowy? Czy ktoś zmienił API i zaniedbał pozostawienie przekierowania.

Dlaczego nie 204 (brak treści)?

Oto fragment opisu kodu stanu 204 przez w3c

Serwer spełnił żądanie, ale nie musi zwracać treści encji i może chcieć zwrócić zaktualizowane metainformacje.

Chociaż w tym przypadku może się to wydawać rozsądne, myślę, że wprowadzałoby to również w błąd klientów. A 204ma wskazywać, że jakaś operacja została wykonana pomyślnie i nie trzeba zwracać żadnych danych. Jest to idealne rozwiązanie jako odpowiedź na DELETEżądanie lub odpalenie jakiegoś skryptu, który nie musi zwracać danych. W przypadku api/usersdomeny zazwyczaj oczekujesz reprezentacji swojej kolekcji użytkowników. Wysyłanie treści odpowiedzi raz, a nie wysyłanie jej innym razem jest niespójne i może wprowadzać w błąd.

Dlaczego miałbym używać 200 (OK)

Z powodów wymienionych powyżej (spójność) zwróciłbym reprezentację pustej kolekcji. Załóżmy, że używasz XML. Normalna treść odpowiedzi dla niepustej kolekcji użytkowników może wyglądać następująco:

<users>
  <user>
    <id>1</id>
    <name>Tom</name>
  </user>
  <user>
    <id>2</id>
    <name>IMB</name>
  </user>
</users>

a jeśli lista jest pusta, możesz po prostu odpowiedzieć w ten sposób (nadal używając a 200):

<users/>

Tak czy inaczej, klient otrzymuje treść odpowiedzi w określonym, dobrze znanym formacie. Nie ma niepotrzebnego zamieszania i sprawdzania kodu statusu. Ponadto nie jest naruszana żadna definicja kodu stanu. Wszyscy są szczęśliwi.

Możesz zrobić to samo z JSON lub HTML lub jakimkolwiek formatem, którego używasz.

toniedzwiedz
źródło
4
Zdecydowanie się zgadzam. I na odpoczynek, ja po prostu odesłać kod statusu 200 z pustej tablicy: [].
Chad Johnson,
Ma sens. Nie musisz tego utrudniać. 404 byłoby mylące.
Witold Kaczurba
Załóżmy API opisujące monety w kieszeni, z punktami końcowymi: GET /singleCoin- zwraca losową pojedynczą monetę z kieszeni, GET /severalCoins- zwraca kilka monet z kieszeni, które możesz wyjąć za jednym razem. Powiedzmy, że w tej chwili nie masz monet w kieszeni. Kiedy poprosisz GET /singleCoin, dostaniesz 404 Not Found, ale kiedy poprosisz GET /severalCoins, otrzymasz 200 OKpustą listę []. Jeden fakt - nie masz monet, opisanych różnymi odpowiedziami, dlaczego? Powiedziałbym, że zawsze lepiej jest je zdobyć 404 Not Found, ponieważ w kieszeni nie ma monet.
sempasha
1
@sempasha To zależy od tego, co masz na myśli GET /severalCoins. Jeśli mandat, że GET /severalCoins musi wrócić kilka monet, to nie powinno być 200, bo to nie jest w porządku; serwer nie dostarczył tego, czego chce klient. Bo /singleCointo jest oczywiste, ponieważ klient chce dokładnie jednej monety, nie więcej, nie mniej. To samo dotyczy /coins/7. W przeciwieństwie do /coinspunktu końcowego, zazwyczaj klienci nie oczekują żadnej monety, jednej monety lub wielu monet. Wszystkie z nich są prawidłową odpowiedzią. Jeśli nie ma monety, to właśnie tego chcą. To jest jak praca List<Coin>w Javie, zamiast null.
Franklin Yu
15

Odpowiedziałbym na jeden z dwóch kodów w zależności od sytuacji w czasie wykonywania:

404 Nie Znaleziono)

Ta odpowiedź jest całkiem poprawna, jeśli nie masz stołu. Nie tylko pusta tabela, ale BRAK TABELI UŻYTKOWNIKÓW. Potwierdza dokładny pomysł - brak zasobów. Dalsze opcje to podanie więcej szczegółów DLACZEGO nie ma twojej tabeli, jest kilka bardziej szczegółowych kodów, ale 404 jest całkiem dobre, aby odnieść się do sytuacji, w której naprawdę nie masz stołu.

200 (OK)

Wszystkie przypadki, w których masz tabelę, ale jest ona pusta lub procesor żądań odfiltrował wszystkie wyniki. Oznacza to, że „Twoje żądanie jest poprawne, wszystko jest w porządku, ale nie dopasowujesz żadnych danych tylko dlatego, że albo nie mamy żadnych danych, albo nie mamy danych, które pasują do Twojego żądania. To powinno być inne niż odpowiedź odmowa bezpieczeństwa. Głosuję również za zwróceniem 200 w sytuacji, gdy masz jakieś dane i ogólnie masz dostęp do tabeli, ale nie masz dostępu do wszystkich danych, które pasują do twojej prośby (dane zostały odfiltrowane ze względu na bezpieczeństwo na poziomie obiektu, ale ogólnie możesz żądanie).

Roman Nikitchenko
źródło
10

Jeśli oczekujesz listy obiektów użytkownika, najlepszym rozwiązaniem jest zwrócenie pustej listy ([]) z 200 OK niż użycie odpowiedzi 404 lub 204.

maniak
źródło
2

zdecydowanie zwraca 200.

404 oznacza, że ​​nie znaleziono zasobu. Ale zasób istnieje. A także, jeśli odpowiedź ma status 404. Skąd możesz wiedzieć, że lista użytkowników jest pusta lub wypełniona?


  • „/ users”, jeśli jest puste, powinno zwrócić „200”.
  • „/ users / 1”, jeśli identyfikator nie zostanie znaleziony. powinien zwrócić 404.
Liva
źródło
2

Musi 200 OK z pustą listą.

Dlaczego: pusta tabela oznacza, że ​​tabela istnieje, ale nie ma żadnych rekordów.

404 Nie znaleziono oznacza, że ​​żądany punkt końcowy nie istnieje.

Amir Raza
źródło