Kod odpowiedzi HTTP dla testu POST, gdy zasób już istnieje


842

Buduję serwer, który pozwala klientom przechowywać obiekty. Obiekty te są w pełni zbudowane po stronie klienta, wraz z identyfikatorami obiektów, które są stałe przez cały okres życia obiektu.

Zdefiniowałem interfejs API, aby klienci mogli tworzyć lub modyfikować obiekty za pomocą PUT:

PUT /objects/{id} HTTP/1.1
...

{json representation of the object}

{Id} jest identyfikatorem obiektu, więc jest częścią identyfikatora URI żądania.

Teraz rozważam również zezwolenie klientom na tworzenie obiektu za pomocą POST:

POST /objects/ HTTP/1.1
...

{json representation of the object, including ID}

Ponieważ POST ma oznaczać operację „dołącz”, nie jestem pewien, co zrobić, jeśli obiekt już tam jest. Czy powinienem traktować to żądanie modyfikacji, czy powinienem zwrócić kod błędu (który)?


5
W czerwcu 2016 r. FB rażąco ustawia 200 na rejestrację, gdy istnieje wiadomość e-mail
Green

4
Github API zwraca 422 podczas próby utworzenia zasobu (zespół / repo) o nazwie, która jest już w użyciu
Ken

1
To zależy, czy uważasz istnienie obiektu za błąd, czy nie. Jeśli przetworzysz dodatek, 200 lub 204 są najbardziej odpowiednimi kodami odpowiedzi.
Suncat2000

Odpowiedzi:


1055

Moje odczucie jest 409 Conflictnajbardziej odpowiednie, jednak rzadko spotykane na wolności:

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

Konflikty najczęściej występują w odpowiedzi na żądanie PUT. Na przykład, jeśli użyto wersjonowania, a obiekt PUT zawierał zmiany w zasobie, które powodują konflikt z zasobami dokonanymi przez wcześniejsze żądanie (strony trzeciej), serwer może użyć odpowiedzi 409, aby wskazać, że nie może zrealizować żądania . W takim przypadku jednostka odpowiedzi prawdopodobnie zawierałaby listę różnic między dwiema wersjami w formacie zdefiniowanym przez typ zawartości odpowiedzi.


11
dlaczego nie wybrać 400 złych wniosków? Dla mnie wygląda to trochę jak błąd sprawdzania poprawności (podajesz nieprawidłowy ładunek z nielegalnym identyfikatorem).
manuel aldana

314
400 => „Serwer nie mógł zrozumieć żądania z powodu nieprawidłowej składni” . Serwer doskonale rozumie, ale nie jest w stanie zastosować się do niego z powodu konfliktu. Nie ma nic złego w żądaniu i składni, tylko problem z danymi. 400 natychmiast sprawiłoby, że uwierzyłem, że cały mechanizm, którego używam, jest wadliwy, a nie tylko dane.
Wrikken 30.09.10

42
@Wrikken To już nie jest poprawne. HTTP R 400 został zmieniony w RFC 7231 w taki sposób, że „serwer nie może lub nie przetworzy żądania z powodu czegoś, co jest postrzegane jako błąd klienta (np. Źle sformułowana składnia żądania, nieprawidłowe sformułowanie komunikatu żądania lub mylące kierowanie żądania”). Nie twierdzę, że 400 jest prawidłowe użycie w tym przypadku, ale może być poprawne z nową definicją 400.
javajavajavajavajava

19
@javajavajavajavajava: wciąż zduplikowane dane nie są moim zdaniem „błędem klienta”, ale oczywiście zależy to od obserwatora.
Wrikken

21
Wracam HTTP 409z Locationnagłówkiem wskazującym na istniejący / sprzeczny zasób.
Gili

100

Zgodnie z RFC 7231 , o 303 Zobacz inne MOGĄ być wykorzystywane Jeśli wynik przetwarzania stanowiska byłoby równoznaczne z reprezentacji istniejącego zasobu .


4
Moim zdaniem może to być dobrze przyjęta odpowiedź. Chociaż „MAY” oznacza element całkowicie opcjonalny, jest to jedyny kod odpowiedzi sugerowany w oficjalnej dokumentacji RFC 7231 .
Nando

16
To jest najbardziej ODPOWIEDNIA odpowiedź.
Seth

6
Myślę, że kontekst jest ważny. Na przykład: zwrócenie wartości 303 oznacza konieczność przekierowania do znalezionego zasobu. Może to mieć sens w rozmowach między serwerami, ale jeśli przeprowadzałeś proces rejestracji użytkownika, nie miałoby to żadnego sensu.
Sinaesthetic

11
Przepraszam, głosuję za tym. HTTP 300 dotyczą przekierowania, a przekierowanie do innego obiektu, który prawdopodobnie ma inne właściwości, byłoby bardzo mylące.
Michael Scheper

6
Nie masz za co przepraszać. Jeśli jednak reprezentacja jest równoważna z istniejącym zasobem, w jaki sposób może mieć różne właściwości? A nawet gdyby tak było, w jaki sposób przekierowanie wprowadzałoby w błąd? OP mówi: nie jestem pewien, co zrobić, jeśli obiekt już tam jest. Jest to w rzeczywistości „ten sam” obiekt. Dlaczego przekierowanie miałoby wprowadzać w błąd? Mówisz o innym obiekcie, który w OP nie jest w oczywisty sposób.
Nullius

86

Osobiście korzystam z rozszerzenia WebDAV 422 Unprocessable Entity.

Zgodnie z RFC 4918

422 Unprocessable EntityKod statusu oznacza, że serwer rozumie treść typ jednostki żądania (stąd 415 Unsupported Media Typekod stanu jest nieodpowiednie) i składnia podmiotu żądanie jest prawidłowe (zatem 400 Bad Requestkod stanu jest niewłaściwe), ale nie był w stanie przetwarzać zawarte instrukcje.


19
Jest to interesująca myśl, która skłoniła mnie do przeczytania dokumentu RFC WebDAV. Myślę jednak, że znaczenie 422 polega na tym, że żądanie i dołączony byt były poprawne pod względem składniowym, ale semantycznie nie miały sensu.
vmj

4
Zniekształcony JSON nie jest bytem poprawnym pod względem składniowym, więc 422
wydaje

7
Nie poszedłbym z tym. Z tego samego adresu URL, do którego odnosi się odpowiedź: „Na przykład ten błąd może wystąpić, jeśli treść żądania XML zawiera dobrze sformułowane (tj. Poprawne składniowo), ale semantycznie błędne instrukcje XML”. Takie jest prawdziwe znaczenie nieprzetworzonej encji, w przeciwieństwie do przypadku wysyłania całkowicie poprawnej encji żądania z prawidłową składnią AND semantyką, ale jedynym problemem jest konflikt z istniejącą encją. W rzeczywistości, jeśli semantyka encji żądania nie byłaby poprawna, w ogóle nie powinna istnieć podobna, istniejąca encja.
Tamer Shlash,

1
Dodanie do komentarza Poskramiacza, jeśli pierwsze żądanie pojawi się jako pierwsze, odniesie sukces, co nie będzie możliwe, jeśli będzie to poprawne semantycznie. Dlatego poprawna semantyka nie miałaby tu zastosowania.
Harish

4
@Tamer Dlaczego tak? Polecenie „Utwórz obiekt xy” jest poprawne pod względem składniowym. Jest semantycznie poprawny tylko wtedy, gdy można utworzyć obiekt xy. Jeśli obiekt xy już istnieje, nie można go już utworzyć, dlatego jest to błąd semantyczny.
Hagen von Eitzen,

47

Chodzi o kontekst , a także o to, kto jest odpowiedzialny za obsługę duplikatów w żądaniach (serwer, klient lub oba)


Jeśli serwer po prostu wskazuje duplikat , spójrz na 4xx:

  • 400 Błędne żądanie - gdy serwer nie przetworzy żądania, ponieważ jest to oczywista wina klienta
  • 409 Konflikt - jeśli serwer nie przetworzy żądania, ale przyczyną tego nie jest wina klienta
  • ...

Aby zobaczyć niejawną obsługę duplikatów, spójrz na 2XX:

  • 200 OK
  • 201 Utworzono
  • ...

jeśli oczekuje się, że serwer coś zwróci , spójrz na 3XX:

  • 302 Znaleziono
  • 303 Zobacz inne
  • ...

gdy serwer jest w stanie wskazać istniejący zasób, oznacza to przekierowanie.


Jeśli powyższe nie wystarczy, zawsze dobrą praktyką jest przygotowanie komunikatu o błędzie w treści odpowiedzi.


2
Żądanie nie powiela zasobu, dodaje dane do jednego. Moim zdaniem Twoja odpowiedź jest najlepsza ze wszystkich.
Suncat2000

28

Może późno do gry, ale natknąłem się na ten problem semantyki, próbując stworzyć interfejs API REST.

Aby nieco rozwinąć odpowiedź Wrikkena, myślę, że możesz użyć jednego 409 Conflictlub 403 Forbiddenzależnie od sytuacji - w skrócie, użyj błędu 403, gdy użytkownik nie może zrobić absolutnie nic, aby rozwiązać konflikt i zrealizować żądanie (np. Nie może wysłać DELETEżądanie jawnego usunięcia zasobu) lub użyj 409, jeśli można coś zrobić.

10.4.4 403 Zabronione

Serwer zrozumiał żądanie, ale odmawia jego spełnienia. Autoryzacja nie pomoże, a prośba NIE POWINNA zostać powtórzona. Jeśli metoda żądania nie była HEAD, a serwer chce podać do publicznej wiadomości, dlaczego żądanie nie zostało spełnione, POWINIEN opisać przyczynę odmowy w jednostce. Jeśli serwer nie chce udostępnić tych informacji klientowi, zamiast tego można użyć kodu stanu 404 (Nie znaleziono).

W dzisiejszych czasach ktoś mówi „403” i przychodzi na myśl problem z uprawnieniami lub uwierzytelnianiem, ale specyfikacja mówi, że to w zasadzie serwer mówi klientowi, że nie zamierza tego zrobić, nie pytaj go ponownie, a oto dlaczego klient nie powinien „t.

Jeśli chodzi o PUTvs. POST... POSTnależy użyć do utworzenia nowej instancji zasobu, gdy użytkownik nie ma środków lub nie powinien utworzyć identyfikatora zasobu. PUTjest używany, gdy znana jest tożsamość zasobu.

9,6 PUT

...

Podstawowa różnica między żądaniami POST i PUT znajduje odzwierciedlenie w innym znaczeniu URI żądania. Identyfikator URI w żądaniu POST identyfikuje zasób, który będzie obsługiwał zamknięty obiekt. Ten zasób może być procesem akceptującym dane, bramą do innego protokołu lub osobnym podmiotem, który przyjmuje adnotacje. W przeciwieństwie do tego, URI w żądaniu PUT identyfikuje encję zawartą w żądaniu - agent użytkownika wie, jaki jest URI, a serwer NIE MOŻE próbować zastosować żądania do jakiegoś innego zasobu. Jeśli serwer chce zastosować żądanie do innego identyfikatora URI,

MUSI wysłać odpowiedź 301 (Moved Permanently); klient użytkownika MOŻE następnie podjąć własną decyzję dotyczącą tego, czy przekierować żądanie.


7
Myślę, że 403 Forbidden oznacza, że ​​nawet jeśli użytkownik jest uwierzytelniony , nie jest on upoważniony do wykonania żądanej akcji. Nie użyłbym tego do błędów sprawdzania poprawności. Przykład : niezalogowany, próbuję coś usunąć. Serwer wysyła mi komunikat 401 Nieautoryzowany (który jest po prostu źle nazwany, powinien być 401 Nieautoryzowany ). Loguję się i próbuję ponownie. Tym razem serwer sprawdza moje uprawnienia, widzi, że nie jestem dozwolony i zwraca 403 Forbidden . Zobacz także to pytanie .
Stijn de Witt

Hm ... prawda. Myśl tutaj skoczyła w prawo, mówiąc użytkownikowi, że dzięki jego autoryzacjom zasób jest niezmienny w przypadku użycia PO - już istnieje, nie masz uprawnień do robienia czegokolwiek w celu rozwiązania konfliktu, nie próbuj ponownie tworzyć zasobu.
p0lar_bear

3
Zgodnie ze specyfikacją implikuje się, że błąd 409 nie może zostać zwrócony przez POSTżądanie (przy prawidłowym użyciu), ponieważ stwierdza, że ​​powinien zostać zwrócony, gdy wystąpi konflikt z zasobem docelowym . Ponieważ zasób docelowy nie został jeszcze zaksięgowany, nie może być w konflikcie, a zatem odpowiedź za pomocą 409 Conflictnie ma żadnego sensu.
Grant Gryczan

1
Nie wywnioskowałbym, że błąd 409 nie może zostać zwrócony przez POST, w rzeczywistości wywnioskowałbym coś przeciwnego, ponieważ „Konflikty najprawdopodobniej wystąpią w odpowiedzi na żądanie PUT”. wydaje się wskazywać, że inne metody żądania mogą również korzystać z tego kodu. Dodatkowo: „Treść odpowiedzi powinna zawierać wystarczającą ilość informacji, aby użytkownik mógł rozpoznać źródło konfliktu. Idealnie, by jednostka odpowiedzi zawierała wystarczającą ilość informacji dla użytkownika lub agenta użytkownika, aby rozwiązać problem; może to jednak nie być możliwe i jest nie wymagane ”. ( webdav.org/specs/rfc2616.html#status.409 )
JWAspin

14

„302 Znaleziono” brzmi dla mnie logicznie. A RFC 2616 mówi, że można odpowiedzieć na inne żądania niż GET i HEAD (i to z pewnością obejmuje POST)

Ale nadal utrzymuje odwiedzającego pod tym adresem URL, aby uzyskać ten „znaleziony” zasób przez RFC. Aby przejść bezpośrednio do rzeczywistego adresu URL „Znaleziony”, należy użyć „303 Zobacz inne”, co ma sens, ale wymusza kolejne wywołanie, aby uzyskać następujący adres URL. Z drugiej strony, ten GET można buforować.

Myślę, że użyłbym „303 See Other” . Nie wiem, czy mogę odpowiedzieć „rzeczą” znalezioną w ciele, ale chciałbym to zrobić, aby zapisać jedną podróż do serwera.

AKTUALIZACJA: Po ponownym odczytaniu RFC nadal uważam, że nieistniejący kod „Znaleziono 4XX + 303” powinien być poprawny. Jednak „konflikt 409” jest najlepszym istniejącym kodem odpowiedzi (jak wskazał @Wrikken), może zawierać nagłówek lokalizacji wskazujący na istniejący zasób.


88
Statusy 3xx są przeznaczone do przekierowania
Aviram Netanel

1
„Żądany zasób znajduje się tymczasowo pod innym identyfikatorem URI.” from w3.org/Protocols/rfc2616/rfc2616-sec10.html
statueofmike

1
IMHO, „307 Temporary Redirect” to prawdziwe tymczasowe przekierowanie. „302” jest niejednoznaczne, ale „ZNALEZIONO !!” jest naprawdę pożądaną wiadomością tutaj. Najlepszym jednoznacznym kompromisem jest „303 See Other” w semantyce HTTP. Wybrałbym „303 See Other”.
alanjds

@DavidVartanian Hum ... Nie widzę tutaj błędu. Klient wysyła prawidłowe żądanie, ale jak powiedzieć „Przepraszam, ale to, co próbujesz tutaj utworzyć, już istnieje”? Wydaje się, że praca dla jakiegoś 3xx. Dla mnie nie jest to 4xx, ponieważ nie ma błędu klienta.
alanjds

1
@DavidVartanian Dzięki za dyskusję. Zaktualizowano odpowiedź w kierunku 409 . Klient błędnie prosi o rzeczy niemożliwe, nawet jeśli nie wie, że jest to niemożliwe.
alanjds

11

Nie sądzę, że powinieneś to zrobić.

POST służy, jak wiadomo, do modyfikacji kolekcji i służy do TWORZENIA nowego elementu. Jeśli więc wyślesz identyfikator (myślę, że to nie jest dobry pomysł), powinieneś zmodyfikować kolekcję, tj. Zmodyfikować element, ale jest to mylące.

Użyj go, aby dodać element bez identyfikatora. To najlepsza praktyka.

Jeśli chcesz przechwycić ograniczenie UNIQUE (nie identyfikator), możesz odpowiedzieć 409, tak jak w żądaniach PUT. Ale nie identyfikator.


Co z obiektem, który ma relację łączenia z tabelą? Powiedzmy, że mamy tabele, produkty i konto_produkty jako tabele bazy danych. Chcę dodać produkt do konta, więc chciałbym opublikować na / account / {id} / product z identyfikatorem produktu. Jeśli dozwolona jest tylko jedna relacja konto-produkt, co mam zwrócić?
partkyle

2
Zapomnij o tabelach bazy danych. Powiedzmy, że produkt może być powiązany tylko z kontem ... To jest relacja jeden do wielu. Zatem POST / product / {id} z {'account': account_id}. Jeśli masz maksymalną liczność ustawioną na „1” (relacja jeden do jednego)… Dlaczego są to oddzielone obiekty odpoczynku? Błąd liczności wyniesie zaledwie 400 błędów. Nie komplikuj. Mam nadzieję, że zrozumiałem twoje pytanie.
Alfonso Tienda,

Właśnie zadałem to pytanie i dla mnie identyfikator nie jest identyfikatorem technicznym w bazie danych, ale jest czymś w rodzaju kodu firmy. W tej aplikacji użytkownik menedżera może tworzyć firmy i musi dać im kod. Jest to identyfikator firmy dla użytkownika, mimo że tabela DB ma również identyfikator techniczny. Więc w moim przypadku zwrócę 409, jeśli ten sam kod firmy już istnieje.
AlexCode,

@partkyle Przestań używać PK jako publicznych identyfikatorów !!
Sinaesthetic

Niektóre podmioty mają unikalne ograniczenia, nie tylko identyfikator. Podobnie jak konto, nie możesz utworzyć konta, jeśli użytkownik nie poda nazwy użytkownika. A dodanie konta bez nazwy użytkownika jest oczywiście niemożliwe
rocketspacer

9

Idę z 422 Unprocessable Entity, który jest używany, gdy żądanie jest nieprawidłowe, ale problem nie dotyczy składni lub uwierzytelnienia.

Jako argument przeciwko innym odpowiedziom użycie dowolnego 4xxkodu innego niż kod błędu oznaczałoby, że nie jest to błąd klienta i oczywiście tak jest. Używanie 4xxkodu innego niż błąd do reprezentowania błędu klienta nie ma żadnego sensu.

Wygląda na to że 409 Conflict jest to najczęstsza odpowiedź tutaj, ale zgodnie ze specyfikacją oznacza to, że zasób już istnieje, a nowe dane, które do niego aplikujesz, są niezgodne z jego bieżącym stanem. Jeśli wysyłaszPOSTżądanie, na przykład z nazwą użytkownika, która jest już zajęta, tak naprawdę nie powoduje konfliktu z zasobem docelowym, ponieważ zasób docelowy (zasób, który próbujesz utworzyć) nie został jeszcze opublikowany. Jest to błąd specyficzny dla kontroli wersji, gdy występuje konflikt między wersją przechowywanego zasobu a wersją żądanego zasobu. Jest to bardzo przydatne w tym celu, na przykład gdy klient zbuforował starą wersję zasobu i wysyła żądanie oparte na tej niepoprawnej wersji, która nie byłaby warunkowo ważna. „W takim przypadku reprezentacja odpowiedzi prawdopodobnie zawierałaby informacje przydatne do scalenia różnic w oparciu o historię zmian.” Prośba o utworzenie innego użytkownika o tej nazwie jest po prostu nieprzetworzona i nie ma nic wspólnego z kontrolą wersji.

Dla przypomnienia, 422 jest także kodem statusu, którego używa GitHub, gdy próbujesz utworzyć repozytorium o nazwie już używanej.


422 jest specyfikacją webdav, więc nie radzę używać tego do interfejsu API REST
rwenz3l

7

Myślę, że w przypadku REST musisz podjąć decyzję dotyczącą zachowania tego konkretnego systemu, w takim przypadku myślę, że „właściwa” odpowiedź byłaby jedną z kilku podanych tutaj odpowiedzi. Jeśli chcesz zatrzymać żądanie i zachowywać się tak, jakby klient popełnił błąd, który należy naprawić przed kontynuowaniem, użyj 409. Jeśli konflikt naprawdę nie jest tak ważny i chcesz kontynuować żądanie, odpowiedz poprzez przekierowanie klient znalezionej jednostki. Myślę, że odpowiednie interfejsy API REST powinny przekierowywać (lub przynajmniej dostarczać nagłówek lokalizacji) do punktu końcowego GET dla tego zasobu po zakończeniu testu POST, więc zachowanie to zapewni spójne działanie.

EDYCJA: Warto również zauważyć, że powinieneś rozważyć PUT, ponieważ podajesz identyfikator. Zatem zachowanie jest proste: „Nie dbam o to, co jest teraz, umieść to tutaj”. Oznacza to, że jeśli nic tam nie będzie, zostanie utworzone; jeśli coś tam jest, zostanie zastąpione. Myślę, że test POST jest bardziej odpowiedni, gdy serwer zarządza tym identyfikatorem. Oddzielenie dwóch pojęć w zasadzie mówi ci, jak sobie z tym poradzić (tj. PUT jest idempotentny, więc zawsze powinien działać tak długo, jak długo ładunek się sprawdza, POST zawsze tworzy, więc jeśli występuje kolizja identyfikatorów, 409 opisałby ten konflikt) .


Zgodnie ze specyfikacją implikuje się, że błąd 409 nie może zostać zwrócony przez POSTżądanie (przy prawidłowym użyciu), ponieważ stwierdza, że ​​powinien zostać zwrócony, gdy wystąpi konflikt z zasobem docelowym . Ponieważ zasób docelowy nie został jeszcze zaksięgowany, nie może być w konflikcie, a zatem odpowiedź za pomocą 409 Conflictnie ma żadnego sensu.
Grant Gryczan

Dyskusyjny imo. Jeśli
wysyłasz

Jest to błąd specyficzny dla kontroli wersji, gdy występuje konflikt między wersją przechowywanego zasobu a wersją żądanego zasobu. Jest to bardzo przydatne w tym celu, na przykład gdy klient zbuforował starą wersję zasobu i wysyła żądanie oparte na tej niepoprawnej wersji, która nie byłaby warunkowo ważna. „W takim przypadku reprezentacja odpowiedzi prawdopodobnie zawierałaby informacje przydatne do scalenia różnic w oparciu o historię zmian.”
Grant Gryczan

Podoba mi się twoja sugestia do wykorzystania PUT.
Grant Gryczan

4

W końcu innym potencjalnym sposobem leczenia jest stosowanie PATCH. PATCH definiuje się jako coś, co zmienia stan wewnętrzny i nie ogranicza się do dołączania.

PATCH rozwiązałby problem, umożliwiając aktualizację już istniejących elementów. Zobacz: RFC 5789: PATCH


2
Łata jest jak PUT, ale nie jest całkowitym zamiennikiem. Służy do modyfikowania fragmentu zasobu, takiego jak dodawanie, usuwanie lub modyfikowanie pojedynczego elementu zasobu zamiast zastępowania go jako całości.
Sinaesthetic

4

Dlaczego nie zaakceptowano 202 ? Jest to żądanie OK (200s), per se nie wystąpiły błędy klienta (400s).

Z 10 definicji kodów stanu :

„202 Zaakceptowano. Żądanie zostało zaakceptowane do przetworzenia, ale przetwarzanie nie zostało zakończone.”

... ponieważ nie trzeba było go wypełniać, ponieważ już istniał. Klient nie wie, że już istniał, nie zrobił nic złego.

Opieram się na rzucaniu 202 i zwracaniu podobnych treści do tego, co /{resource}/{id}zwróciłby GET .


21
Ta odpowiedź jest zła. 202 oznacza, że ​​serwer nie znalazł problemu z żądaniem, ale zdecydował się przetworzyć żądanie po odpowiedzi. Oznacza to również, że oczekuje, że przetwarzanie zakończy się powodzeniem. W naszym przypadku serwer wie, że przetwarzanie zakończy się niepowodzeniem, więc 202 jest złą odpowiedzią.
Adrian

4
Przykładem 202 może być kolejka lub subskrypcja. Innymi słowy, wynik żądania może nie być dostępny natychmiast, jeśli w tym momencie zapytasz go o to.
Sinaesthetic

1
Byłoby to właściwe, gdyby serwer nadal przetwarzał żądanie. 200 lub 204 byłyby bardziej powszechne. Ponieważ OP wysyła żądanie dołączenia, istnienie obiektu jest oczekiwanym warunkiem, a nie błędem.
Suncat2000

Nie ma sensu mówić klientowi, że prośba została zaakceptowana, ponieważ już wiesz, że tak nie było!
lucastamoios

1
@Adrian i lucastamoios, myślę, że oboje zakładacie, że serwer synchronicznie czyta dane z bazy danych, zanim udzieli odpowiedzi. Nie zawsze tak jest, więc odpowiedź nie jest „zła”, ponieważ serwer nie zawsze „wie” o istniejącym rekordzie. Dotyczy to w szczególności systemów asynchronicznych, w których warstwa interfejsu API po prostu rejestruje żądania przetwarzania przez pracowników działających w tle.
gsaslis

2

Natknąłem się na to pytanie, sprawdzając poprawność kodu dla duplikatu rekordu.

Przepraszam za moją ignorancję, ale nie rozumiem, dlaczego wszyscy ignorują kod „300”, który wyraźnie mówi „wielokrotny wybór” lub „dwuznaczny”

Moim zdaniem byłby to idealny kod do budowy niestandardowego lub konkretnego systemu na własny użytek. Mogę się również mylić!

https://tools.ietf.org/html/rfc7231#section-6.4.1


Rozumiem: ”kod stanu wskazuje, że zasób docelowy ma więcej niż jedną reprezentację ... podano informacje o alternatywach, aby użytkownik (lub agent użytkownika) mógł wybrać preferowaną reprezentację poprzez przekierowanie swojego żądania do jednej lub więcej z nich identyfikatory „Staramy się wyraźnie zapobiec kilku reprezentacjom. Brak opcji. Klient nie ma innego wyboru. Klient powinien ponownie przesłać z innym identyfikatorem. Mając to na uwadze, należy również rozważyć, czy unikalne identyfikatory powinny być generowane w kliencie kontra serwerze.
musicin3d

Semantycznie, klient mówi „Utwórz to”, a serwer odpowiada, mówiąc „Idź tutaj”. Rozmowa nie ma sensu. To prawie tak, jakby serwer kazał klientowi „zamiast tego wysłać wiadomość do tej lokalizacji”. 300s są bardziej odpowiednią odpowiedzią na żądanie GET lub POST w przypadku, gdy serwer odpowiada „Ok, stworzyłem go i już tu jest” ..
Sinaesthetic

2

Bardziej prawdopodobne jest 400 Bad Request

6.5.1 400 złych wniosków


Kod statusu 400 (Błędne żądanie) wskazuje, że serwer nie może lub nie przetworzy żądania z powodu czegoś, co jest postrzegane jako błąd klienta (np. Źle sformułowana składnia żądania, nieprawidłowe sformułowanie komunikatu żądania lub oszukańczy routing żądania).

Ponieważ żądanie zawiera zduplikowaną wartość (wartość, która już istnieje), może być postrzegane jako błąd klienta. Musisz zmienić żądanie przed następną próbą.
Uwzględniając te fakty, możemy stwierdzić, że błędny wniosek HTTP STATUS 400.


1
Złe żądanie oznacza, że ​​istnieje nieodłączny problem ze składnią pakietu. Jeśli w innym kontekście (np.
Nieistniejącym zasobie

1

Co z 208 - http://httpstatusdogs.com/208-already-reported ? Czy to jest opcja?

Moim zdaniem, jeśli jedyną rzeczą jest powtarzanie zasobów, nie należy zgłaszać błędów. W końcu nie ma błędu ani po stronie klienta, ani serwera.


Nie ma takiej opcji, ponieważ chcesz dołączyć określony element, którego identyfikator już istnieje. Więc próbujesz coś dodać, ale to już jest. OK miałoby zastosowanie tylko wtedy, gdy zestaw danych został powiększony. Append Something -> Ok Nic nie dodałem. Chyba nie pasuje.
Martin Kersten,

Jak powiedziałem, nie sądzę, że to błąd. Ale widzę sens @martin
Fernando Ferreira

Jeśli zasób nie zostanie pomyślnie utworzony, oznacza to błąd z definicji.
Grant Gryczan

POST służy również do dołączania danych. Jest to z definicji , nie jest błędem .
Suncat2000

@ Suncat2000 Nawet jeśli tak jest, jeśli dane nie zostaną pomyślnie dołączone, nadal występuje błąd. A jeśli zasób już istnieje, żadne dane nie będą dołączane.
Grant Gryczan
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.