Powiedziałbym, że może być poprawny kod odpowiedzi 200 lub 404 , w zależności od tego, jak spojrzysz na sytuację.
Chodzi o to, że kody odpowiedzi HTTP są zdefiniowane w kontekście serwera , który może dostarczać różne zasoby na podstawie ich adresów URL. W tym kontekście znaczenia 200 OK
i 404 Not Found
są całkowicie jednoznaczne: pierwsza mówi „oto zasób, o który prosiłeś”, a druga mówi „przepraszam, nie mam takich zasobów”.
Jednak w twojej sytuacji istnieje dodatkowa warstwa aplikacji między serwerem HTTP a rzeczywistymi żądanymi zasobami (drzewami). Aplikacja zajmuje rodzaj przestrzeni pośredniej, która nie jest dobrze zaadresowana w specyfikacji HTTP.
Z punktu widzenia serwera sieciowego, zastosowanie wygląda trochę jak zasób: to zazwyczaj plik na serwerze, zidentyfikowanego przez (część) adres URL, podobnie jak innych zasobów (np statycznych plików) serwer może służyć. Z drugiej strony jest to dziwny rodzaj zasobu, ponieważ składa się z kodu wykonywalnego, który dynamicznie określa treść, a nawet potencjalnie kod statusu odpowiedzi, dzięki czemu zachowuje się w pewien sposób bardziej jak mini-serwer.
W szczególności, w twoim przypadku serwer WWW może dobrze zlokalizować aplikację, ale aplikacja nie może zlokalizować żądanego podkatalogu (drzewa). Teraz, jeśli uważasz aplikację za rozszerzenie serwera , a podelement (drzewo) za rzeczywisty zasób, to odpowiednia jest odpowiedź 404 : serwer jedynie przekazał zadanie znalezienia rzeczywistego zasobu do aplikacji , które jej się nie udało.
Z drugiej strony, jeśli twoim zdaniem jest to, że aplikacja jest żądanym zasobem , serwer sieci powinien oczywiście zwrócić odpowiedź 200 ; w końcu aplikacja została znaleziona i wykonana poprawnie. Oczywiście w tym przypadku aplikacja powinna faktycznie zwrócić poprawną treść odpowiedzi w oczekiwanym formacie, wskazując (używając dowolnego protokołu wyższego poziomu, który koduje ten format), że nie znaleziono żadnych rzeczywistych danych pasujących do zapytania.
Oba te punkty widzenia mogą mieć sens. W większości przypadków , przynajmniej w przypadku aplikacji przeznaczonych do bezpośredniego dostępu przez HTTP za pomocą zwykłej przeglądarki internetowej, wolałbym poprzedni widok : użytkownik zasadniczo nie dba o szczegóły wewnętrzne, takie jak różnica między serwerem a aplikacją, po prostu dbać o to, czy dane, których chcieli, są, czy nie.
Jednak w konkretnym przypadku aplikacji zaprojektowanej do komunikowania się z innymi programami komputerowymi przy użyciu niestandardowego protokołu API wysokiego poziomu, wykorzystującego HTTP tylko jako warstwę transportową niskiego poziomu , należy argumentować na korzyść tego drugiego widoku : dla klienci współpracujący z taką aplikacją, wszystko, na czym naprawdę im zależy, na poziomie HTTP , to to, czy udało im się pomyślnie skontaktować z aplikacją, czy nie. Cała reszta jest w takich przypadkach często bardziej naturalnie komunikowana przy użyciu protokołu wyższego poziomu.
W każdym razie, niezależnie od tego, który z powyższych widoków preferujesz, jest kilka szczegółów, o których powinieneś pamiętać. Jednym z nich jest to, że w wielu przypadkach może istnieć znaczące rozróżnienie między (zasadniczo) pustym zasobem a nieistniejącym zasobem .
Na poziomie HTTP pusty zasób byłby po prostu oznaczony kodem 200 odpowiedzi i pustym ciałem odpowiedzi, natomiast nieistniejący zasób byłby wskazany przez odpowiedź 404 i treść zasobu wyjaśniającą brak zasobu. W protokole API wyższego poziomu zwykle wskazuje się na nieistniejący zasób za pomocą odpowiedzi na błąd, zawierającej odpowiedni kod / komunikat błędu specyficzny dla protokołu, natomiast pusta odpowiedź byłaby po prostu normalną strukturą odpowiedzi bez elementów danych.
(Zauważ, że zasób nie musi być dosłownie długi na zero bajtów, aby był „pusty” w sensie, o którym mowa powyżej. Na przykład wynik wyszukiwania bez pasujących elementów byłby liczony jako pusty w szerokim znaczeniu, tak jak wynik zapytania SQL z bez wierszy lub dokumentu XML nie zawierającego rzeczywistych danych).
Ponadto, oczywiście, jeśli aplikacja naprawdę nie wierzy, że żądana subresource powinno tam być, ale nie może go znaleźć, potem trzeci możliwy kod odpowiedzi istnieje: 500 Internal Server Error
. Taka odpowiedź ma sens, jeśli istnienie zasobu jest założonym warunkiem wstępnym aplikacji, tak że jego brak koniecznie oznacza wewnętrzną awarię.
Wreszcie, należy zawsze pamiętać o prawie Postela :
„ Bądź konserwatywny w tym, co wysyłasz, i liberalny w tym, co otrzymujesz ”.
Niezależnie od tego, czy serwer powinien odpowiedzieć w konkretnej sytuacji odpowiedzią 200, czy 404, nie usprawiedliwia to, jako implementatora klienta, odpowiedniej obsługi odpowiedzi w sposób maksymalizujący niezawodną interoperacyjność. Oczywiście można argumentować, co oznacza „odpowiednie” postępowanie w różnych sytuacjach, ale z pewnością nie powinno to normalnie obejmować awarii lub „rozpadu”.
/GoalTree/GetById?versionId=CompletelyInvalidID
zwrócić? Niepowodzenie, ponieważ wymieniony zasób/GoalTree/GetById?versionId=CompletelyInvalidID
dosłownie nie został znaleziony.