Ponieważ żądania HTTP w systemie bezstanowym powinny być niezależne, wyniki jednego żądania nie powinny być zależne od poprzedniego żądania. Zastanów się, co powinno się stać, jeśli dwóch użytkowników wykonało jednocześnie DELETE na tym samym zasobie. Sensowne jest, aby drugie żądanie otrzymało błąd 404. To samo powinno mieć miejsce, jeśli jeden użytkownik wysyła dwa żądania.
Domyślam się, że posiadanie DELETE zwracania dwóch różnych odpowiedzi nie jest dla ciebie idempotentne. Uważam, że przydatne jest myślenie o idempotentnych żądaniach jako pozostawiających system w tym samym stanie, niekoniecznie mających taką samą odpowiedź. Zatem niezależnie od tego, czy USUWASZ istniejący zasób, czy spróbujesz USUNĄĆ zasób, który nie istnieje, stan zasobu serwera jest taki sam.
rm
.rm
zwraca błąd, jeśli nie istnieje. tools.ietf.org/html/rfc7231#section-4.3.5Książka kucharska usług internetowych RESTful jest doskonałym źródłem informacji na ten temat. Przypadkowo jego podgląd w Google pokazuje stronę o DELETE (strona 11):
źródło
Zgadzam się z tym, co mówi aktualnie wybrana odpowiedź, że druga (i trzecia, czwarta, ...) DELETE powinna otrzymać 404 . Zauważyłem, że odpowiedź ma 143 głosów pozytywnych, ale ma również przeciwny komentarz, który ma 54 głosów pozytywnych, więc społeczność jest podzielona na 2 obozy w stosunku mniej więcej 3: 1. Oto więcej informacji, które pozwolą rozstrzygnąć tę długą debatę.
Przede wszystkim NIE zaczynajmy od tego, co „ja” myślę, co „ty” myślisz, ani co myśli inny autor książki. Zacznijmy od specyfikacji HTTP, tj. RFC 7231.
DELETE /some/resource/which/does/not/exist
powinno skutkować błędem 404. WtedyDELETE /some/resource/which/happened/to/be/removed/by/someone/else/five/days/ago
równie dobrze możemy również zwrócić 404 W takim razie dlaczego miałobyDELETE /some/resource/i/deleted/five/seconds/ago
być inaczej? „Ale co powiesz na idempotencję ?!”, słyszę, że tak krzyczysz. Poczekaj, zaraz się tym zajmiemy.Historycznie rzecz biorąc, specyfikacja RFC 2616, opublikowana w 1999 r., Była najczęściej wymienianą specyfikacją HTTP 1.1. Niestety jego opis idempotencji był niejasny , co pozostawia miejsce na wszystkie te debaty. Ale ta specyfikacja została zastąpiona przez RFC 7231. Cytat z RFC 7231, sekcja 4.2.2 Idempotent Methods , wyróżnienie moje:
Tak więc jest napisane w specyfikacji, idempotencja dotyczy wpływu na serwer. Pierwsze DELETE zwracające 204, a następnie DELETE zwracające 404, taki inny kod stanu NIE powoduje, że DELETE nie jest idempotentny. Użycie tego argumentu do uzasadnienia kolejnego zwrotu 204 jest po prostu nieistotne.
OK, więc nie chodzi o idempotencję. Ale w takim razie pytanie uzupełniające może brzmieć, co jeśli nadal zdecydujemy się użyć 204 w kolejnym DELETE? Czy to jest w porządku?
Dobre pytanie. Motywacja jest zrozumiała: pozwolić klientowi na osiągnięcie zamierzonego wyniku, bez martwienia się o obsługę błędów. Powiedziałbym, że zwrócenie 204 w kolejnym DELETE jest w dużej mierze nieszkodliwym „białym kłamstwem” po stronie serwera, którego strona klienta nie zauważy od razu różnicy. Dlatego około 25% ludzi robi to na wolności i wydaje się, że nadal działa. Pamiętaj tylko, że takie kłamstwo można uznać za dziwne semantycznie, ponieważ
GET /non-exist
zwraca 404, aleDELETE /non-exist
daje 204, w tym momencie klient zorientowałby się, że twoja usługa nie jest w pełni zgodna z sekcją 6.5.4 404 Not Found .Chcę jednak zaznaczyć, że zamierzony sposób wskazany przez RFC 7231, tj. Zwrócenie 404 przy kolejnym DELETE, nie powinien być problemem w pierwszej kolejności. 3 razy więcej programistów zdecydowało się to zrobić i czy kiedykolwiek słyszałeś poważny incydent lub skargę spowodowaną przez klienta, który nie był w stanie obsłużyć błędu 404? Prawdopodobnie nie, a to dlatego, że każdy przyzwoity klient, który implementuje HTTP DELETE (lub jakąkolwiek metodę HTTP, jeśli o to chodzi), nie założyłby ślepo, że wynik zawsze będzie pomyślny 2xx. A potem, gdy programista zacznie rozważać obsługę błędów, błąd 404 Not Found byłby jednym z pierwszych błędów, jakie przyjdą na myśl. W tym momencie prawdopodobnie wyciągnąłby wniosek, że jest semantycznie bezpieczne dla operacji HTTP DELETE zignorowanie błędu 404. I tak zrobili.
Problem rozwiązany.
źródło
Najpierw USUŃ : 200 lub 204.
Kolejne USUNIĘCIA : 200 lub 204.
Uzasadnienie : DELETE powinno być idempotentne. Jeśli wrócisz 404 na drugi DELETE, Twoja odpowiedź zmienia się z kodem sukcesu do kodu błędu . Program klienta może podejmować niepoprawne działania przy założeniu, że DELETE nie powiodło się.
Przykład :
Aby zilustrować zastosowanie tego podejścia, przewodnik po stylu interfejsu API protokołu HTTP dla systemu PayPal zawiera następujące wytyczne:
źródło