2012-05-23 20 views
18

Wyobraź sobie serwis internetowy REST, w którym dodajesz elementy do jakiegoś typu kontenera. Na przykład, powiedzmy, że możemy dodać uczestników organizowanych # 789 do zdarzenia nr 456 tak:Czy HTTP 404 jest odpowiednią odpowiedzią dla operacji PUT, w której nie znaleziono jakiegoś powiązanego zasobu?

PUT http://..../api/v1/events/456/attendees/789 

Jeśli któryś zdarzenie nr 456 lub obecnościach # 789 nie istnieje, jest to prawidłowe, aby powrócić HTTP 404 (wraz ze szczegółowym ładunkiem błędu wyjaśniającym, na czym polegał problem, np. { "error" : { "message" : "Event 456 does not exist" , "code" : "404" } }?

Podobnie, jeśli tworzę coś nowego, co odnosi się do innego obiektu, ale drugi obiekt nie istnieje? Na przykład wyobraź sobie, że tworzę wydarzenie w lokalizacji # 123

PUT http://..../api/v1/event 
{ "location": 123, "name": "Party", "date": "2012-05-23", ...etc... } 

Jeśli Lokalizacja nr 123 nie istnieje, czy poprawne jest również zwracanie 404 (wraz z szczegółami w odpowiedzi)? Jeśli nie, co byłoby właściwe - po prostu 400?

Według specyfikacji HTTP 1.1 http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html

9,6 PUT ... Jeśli zasób nie mógł zostać utworzony lub zmodyfikowany z żądaniem-URI, odpowiednia reakcja na błąd należy przyznać, że odzwierciedla charakter problemu

Tak, że wydaje się być dobry głos do reagowania z 404. jednak z jakiegoś powodu nie mogę całkiem umieścić mój palec, odpowiadając na PUT (lub POST) z 404 wydaje dziwne dla ja ... Być może dlatego, że 404 oznacza, że ​​zasobu nie można znaleźć, ale w tym przypadku nasz zasób jest w rzeczywistości powiązaniem między dwoma innymi zasobami i jest jednym z tych dwóch zasobów, których nie można znaleźć.

Nie przejmujcie się zbytnio moimi dokładnymi przykładami tutaj - są one sporządzone w celu zilustrowania tego. Główne pytanie brzmi: czy 404 jest właściwą odpowiedzią na operację PUT, która nie działa, ponieważ nie znaleziono powiązanego zasobu?

Byłoby wspaniale, gdyby można było wskazać odniesienia - ciężko jest mi znaleźć takie, które uzyskają taki poziom szczegółowości i są wystarczająco wiarygodne. Szczególnie w odniesieniu do traktowania relacji z zasobami w projekcie interfejsu REST API.

Zaktualizowane myślenie Myślę, że prawdopodobnie pierwszy przykład powinien powrócić 404, drugi nie powinien. Rozumowanie polega na tym, że w pierwszym przypadku dodawany przez nas zasób używa zdarzenia 456 i uczestnika 789 jako złożonego klucza podstawowego; druga lokalizacja sprawy to tylko klucz obcy. W drugim przypadku powinien zostać zwrócony błąd, ale nie 404 - prawdopodobnie 412 warunków wstępnych nie powiodło się lub może tylko 400 złych wniosków. Myśli?

+1

IMHO z perspektywy klienta uruchamiasz z katalogu głównego ('/') i idąc ścieżką. Jeśli w którymś momencie nie znajdziesz części ścieżki, powinieneś rzucić 404 z niecierpliwością. Byłoby miło, gdybyś mógł podać, która część faktycznie zawiodła, ale uważam, że 404 jest uzasadnione. –

Odpowiedz

14

Istnieje liczba 4xx HTTP status codes. Najbardziej prawdopodobne są albo 404 lub 409:

404 Not Found

Serwer nie znalazł niczego dopasowanie skutecznego żądania URI. Nie podano, czy warunek jest tymczasowy, czy nie. Kod stanu 410 (Gone) POWINIEN być użyty, jeśli serwer wie przez pewien wewnętrzny konfigurowalny mechanizm, że stary zasób jest trwale niedostępny i nie ma adresu przekierowania. Ten kod stanu jest często używany, gdy serwer nie chce, aby ujawnił dokładnie, dlaczego odrzucono żądanie lub gdy nie ma zastosowania żadna inna odpowiedź .

409 Konflikt

Żądanie nie mogło być zakończone z powodu konfliktu z obecnym stanu zasobu. Ten kod jest dozwolony tylko w sytuacjach, w których oczekuje się, że użytkownik może rozwiązać konflikt i ponownie przesłać żądanie. Ciało odpowiedzi powinno zawierać wystarczającą ilość informacji, aby użytkownik mógł rozpoznać źródło konfliktu. Idealnie, reprezentacja odpowiedzi zawierałaby wystarczającą informację dla użytkownika lub agenta użytkownika, aby rozwiązać problem; może to jednak nie być możliwe i nie jest wymagane.

Konflikty najprawdopodobniej wystąpią w odpowiedzi na żądanie PUT. W przypadku przykładu , jeśli używane było wersjonowanie, a reprezentacja to PUT zawierała zmiany w zasobie, który jest niezgodny z żądaniem zgłoszonym przez wcześniejsze żądanie (strony trzeciej), serwer może użyć odpowiedzi 409 , aby wskazać, że może ". t uzupełnić wniosek. W tym przypadku reprezentacja odpowiedzi prawdopodobnie zawiera listę różnic między dwiema wersjami.

Każda z tych byłby odpowiedni, ale myślę, że pójdę do 409. 404 jest używany do URI nie znaleziono ale 409 wskazuje aktualny stan zasobów nie pozwala na działanie wymagane. W twoim przypadku żądanie nie może zostać spełnione, ponieważ coś jest nie w porządku, co na to nie pozwala.

+0

409 to możliwy wybór. Część o "użytkownik może być w stanie rozwiązać konflikt i ponownie przesłać żądanie" jest interesującą zmarszczką. Co się stanie, jeśli weźmiemy przykład, że lokalizacji nie można dodać za pomocą interfejsu API, a być może nie przez użytkownika ze względu na ich poziom zabezpieczeń - czy 409 jest nadal ważny? Czy jest to mylące, jeśli zwracamy 404 dla tego typu błędu, a 409 dla innych, prawie identycznych błędów, gdy użytkownik _ może_ używać API do dodawania brakującego elementu? ... Mimo wszystko 409 może nie mieć sensu, ponieważ użytkownicy prawdopodobnie _ nie mogą utworzyć lokalizacji o identyfikatorze # 123, zakładając, że jest to automatycznie przypisany klucz ... – jlarson

+1

@joelarson: Nie mówi * jak * użytkownik powinien rozwiązać konflikt . Być może wysyłając wiadomość e-mail z informacją "Dodaj lokalizację 123", w odpowiedzi może zostać udzielona informacja, jak to zrobić. Twierdzę, że jeśli sytuacja jest "Nie można zrobić X z powodu sytuacji Y", to jest 409; jeśli "Nie mogę zlokalizować URI" X ", to jest 404. –

Powiązane problemy