REST kody statusu HTTP dla nieudanej walidacji lub nieprawidłowego duplikatu

Buduję aplikację z API opartym na REST i doszedłem do punktu, w którym określam kody statusu dla każdego żądania.

Jaki kod statusu należy wysłać dla żądań, które nie zostały zweryfikowane lub w przypadku, gdy żądanie próbuje dodać duplikat do mojej bazy danych?

Przejrzałem http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html ale żadne z nich nie wydaje się właściwe.

Czy istnieje powszechna praktyka wysyłania kodów statusu?

Author: Raedwald, 2010-07-20

8 answers

Dla błędu walidacji danych wejściowych: 400 Bad Request + opcjonalny opis. Jest to sugerowane w książce "RESTful Web Services ". For double submit: 409 Conflict


Aktualizacja Czerwiec 2014

Odpowiednią specyfikacją był RFC2616 , co dało użycie 400 (Bad Request) raczej wąsko jako

Żądanie nie może być zrozumiane przez serwer z powodu nieprawidłowej składni

Więc to być może były argumentowane, że było to nieodpowiednie dla błędów semantycznych. Od czerwca 2014 r. odpowiedni standard RFC 7231, który zastępuje poprzedni RFC2616, daje użycie 400 (Bad Request) szerzej jako

Serwer nie może lub nie przetworzy wniosku z powodu czegoś, co jest postrzegane jako błąd klienta

 627
Author: deamon,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-09-23 17:50:20
  • nieudana Walidacja: 403 Forbidden ("serwer zrozumiał żądanie, ale odmawia jego spełnienia"). Wbrew powszechnej opinii, RFC2616 nie mówi "403 jest przeznaczony tylko do nieudanego uwierzytelniania", ale "403: wiem, czego chcesz, ale tego nie zrobię". Warunek ten może, ale nie musi być spowodowany uwierzytelnieniem.
  • próba dodania duplikatu: 409 Conflict ("żądanie nie może zostać zakończone z powodu konfliktu z aktualnym stanem zasobu.")

Powinieneś zdecydowanie podaj bardziej szczegółowe wyjaśnienie w nagłówkach odpowiedzi i/lub Treści (np. z niestandardowym nagłówkiem - X-Status-Reason: Validation failed).

 252
Author: Piskvor,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-11-21 22:51:41

Polecam status code 422, "Unprocessable Entity" .

11.2. 422 Unprocessable Entity

Kod statusu 422 (Unprocessable Entity) oznacza, że serwer rozumie typ zawartości jednostki żądania(stąd kod stanu 415 (nieobsługiwany typ nośnika) jest niewłaściwy), a składnia jednostki żądania jest prawidłowa (zatem kod stanu 400 (Bad Request) jest niewłaściwy), ale nie był w stanie przetworzyć zawartych instrukcji. Na przykład ten błąd warunek może wystąpić, jeśli ciało żądania XML zawiera dobrze uformowane (tj. poprawne składniowo), ale semantycznie błędne instrukcje XML.

 171
Author: Julian Reschke,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-10-10 09:25:23

200,300, 400, 500 wszystkie są bardzo ogólne. Jeśli chcesz generic, 400 jest OK.

[[1]} 422 jest używany przez coraz większą liczbę interfejsów API, a nawet jest używany przez Rails po wyjęciu z pudełka.

Bez względu na to, który kod statusu wybierzesz dla swojego API, ktoś się nie zgodzi. Ale wolę 422, ponieważ uważam "400 + status tekstu" za zbyt ogólny. Ponadto nie korzystasz z parsera gotowego do JSON; w przeciwieństwie do tego, 422 z odpowiedzią JSON jest bardzo wyraźny, a wiele informacji o błędach może być przenoszone.

Mówiąc o odpowiedzi JSON, mam tendencję do standaryzacji odpowiedzi na błędy Rails w tym przypadku, czyli:

{
    "errors" :
    { 
        "arg1" : ["error msg 1", "error msg 2", ...]
        "arg2" : ["error msg 1", "error msg 2", ...]
    }
}

Ten format jest idealny do walidacji formularzy, co uważam za najbardziej złożony przypadek do obsługi pod względem "bogactwa raportowania błędów". Jeśli twoja struktura błędów jest taka, prawdopodobnie obsłuży wszystkie twoje potrzeby raportowania błędów.

 70
Author: sethcall,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-11-02 22:23:59

Duplikat w bazie danych powinien być 409 CONFLICT.

Zalecam użycie 422 UNPROCESSABLE ENTITY do błędów walidacji.

Podaję tu dłuższe Wyjaśnienie kodów 4xx: http://parker0phil.com/2014/10/16/REST_http_4xx_status_codes_syntax_and_sematics/

 28
Author: Phil Parker,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-10-16 23:05:13

200

Ugh... (309, 400, 403, 409, 415, 422)... wiele odpowiedzi próbuje odgadnąć, argumentować i standaryzować, jaki jest najlepszy kod powrotu dla pomyślnego żądania http , Ale nieudanego wywołania rest .

Jest źle mieszać kody protokołu HTTP i wyniki REST.

Widziałem jednak wiele implementacji je mieszających i wielu programistów może się ze mną nie zgodzić.

Kody zwrotne HTTP są powiązane z samym HTTP Request. Wywołanie REST jest zrobione używając żądania protokołu transferu hipertekstowego i działa na niższym poziomie niż wywołana sama metoda REST. REST jest koncepcją / podejściem,a jego wynikiem jest biznesowy/logiczny wynik, podczas gdy kod wyniku HTTP to transport .

Na przykład zwracanie "404 Not found" podczas wywoływania /users / jest mylące, ponieważ może oznaczać:

  • URI się myli (HTTP)
  • nie znaleziono użytkowników (reszta)

"403 Forbidden/Access Denied" may średnia:

  • potrzebne specjalne pozwolenie. Przeglądarki mogą sobie z tym poradzić, pytając użytkownika / hasło. (HTTP)
  • błędne uprawnienia dostępu skonfigurowane na serwerze. (HTTP)
  • musisz być uwierzytelniony (reszta)

I lista może być kontynuowana z " 500 Server error "(Błąd rzuconego HTTP Apache/Nginx lub błąd ograniczenia biznesowego w REST) lub innymi błędami HTTP itp...

Z kodu, trudno zrozumieć, co było przyczyną awarii, HTTP (transport) niepowodzenie lub odpoczynek (logiczny) niepowodzenie.

Jeśli żądanie HTTP zostało fizycznie wykonane pomyślnie, powinno Zawsze zwracać kod 200, niezależnie od tego, czy rekord(y) został znaleziony, czy nie. Ponieważ zasobem URI jest znaleziony i był obsługiwany przez serwer http. Tak, może zwrócić pusty zestaw. Czy jest możliwe, aby otrzymać pustą stronę internetową z 200 jako wynik http, prawda?

Zamiast tego możesz zwrócić 200 kod HTTP z kilkoma opcjami:

  • obiekt"error" w JSON wynik jeśli coś pójdzie nie tak
  • Empty JSON array / object if no record found
  • znacznik wyniku/sukcesu bool w połączeniu z poprzednimi opcjami dla lepszej obsługi.

Ponadto niektórzy dostawcy Internetu mogą przechwycić Twoje żądania i zwrócić Ci kod http 404. Nie oznacza to, że Twoje dane nie zostaną znalezione, ale jest to coś złego na poziomie transportu.

From Wiki :

W lipcu 2004 r. Brytyjski dostawca usług telekomunikacyjnych BT Group wdrożył Cleanfeed system blokowania treści, który zwraca błąd 404 do każdego żądania treści uznane przez Internet Watch za potencjalnie nielegalne Fundacja. Inni dostawcy usług internetowych zwracają błąd HTTP 403 "forbidden" w tym samym okoliczności. Praktyka stosowania fałszywych błędów 404 jako środka do cenzura ukrywana była także w Tajlandii i Tunezji. W Tunezja, gdzie cenzura była ostra przed rewolucją 2011, ludzie zdali sobie sprawę z natury fałszywych błędów 404 i stworzył wyimaginowana postać o nazwie "Ammar 404", która reprezentuje " niewidzialne cenzor".

Dlaczego po prostu nie odpowiedzieć czymś takim?

{
  "result": false,
  "error": {"code": 102, "message": "Validation failed: Wrong NAME."}
}

Google zawsze zwraca 200 jako kod stanu w interfejsie API geokodowania, nawet jeśli żądanie logicznie nie powiedzie się: https://developers.google.com/maps/documentation/geocoding/intro#StatusCodes

 10
Author: Marcodor,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-05-29 06:09:37

Kod statusu 304 niezmodyfikowany stanowi również akceptowalną odpowiedź na zduplikowane żądanie. Jest to podobne do przetwarzania nagłówka If-None-Match za pomocą znacznika encji.

Moim zdaniem odpowiedź @Piskvor jest bardziej oczywistym wyborem do tego, co widzę, to intencja pierwotnego pytania, ale mam alternatywę, która jest również istotna.

Jeśli chcesz traktować duplikat żądania jako ostrzeżenie lub powiadomienie, a nie jako błąd, kod statusu odpowiedzi 304 nie Zmodyfikowany i Content-Location nagłówek identyfikujący istniejący zasób byłby równie ważny. Gdy celem jest jedynie zapewnienie istnienia zasobu, duplikat żądania nie byłby błędem, ale potwierdzeniem. Żądanie nie jest błędne, ale jest po prostu zbędne, a Klient może odwołać się do istniejącego zasobu.

Innymi słowy, żądanie jest dobre, ale ponieważ zasób już istnieje, serwer nie musi wykonywać żadnego dalszego przetwarzania.

 6
Author: Suncat2000,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-03-17 19:53:47

Adapter ActiveRecord Ember-Data oczekuje, że 422 UNPROCESSABLE ENTITY zostanie zwrócone z serwera. Więc, jeśli jesteś klientem jest napisane w Ember.js powinieneś użyć 422. Tylko wtedy DS.Błędy zostaną uzupełnione o zwrócone błędy. Możesz oczywiście zmienić 422 na dowolny inny kod w swoim adapterze.

 6
Author: Daniel Kmak,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-12-03 22:17:18