Tworzę aplikację z interfejsem API opartym na REST i doszedłem do momentu, w którym określam kody stanu dla każdego żądania.
Jaki kod stanu powinienem wysłać w przypadku wniosków, które nie sprawdzają poprawności 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 żaden z nich nie wydaje się odpowiedni.
Czy istnieje powszechna praktyka podczas wysyłania kodów stanu?
http
rest
http-status-codes
alexn
źródło
źródło
Odpowiedzi:
W przypadku niepowodzenia sprawdzania poprawności danych wejściowych: 400 Błędne żądanie + opcjonalny opis. Jest to sugerowane w książce „ RESTful Web Services ”. W przypadku podwójnego zgłoszenia: 409 Konflikt
Aktualizacja z czerwca 2014 r
Odpowiednią specyfikacją był RFC2616 , który dawał użycie 400 (Bad Request) raczej wąsko jako
Więc to może być twierdził, że to było niewłaściwe błędów semantycznych. Ale już nie; od czerwca 2014 r. odpowiednia norma RFC 7231 , która zastępuje poprzednią RFC2616, daje szersze zastosowanie 400 (Złe żądanie) jako
źródło
something perceived to be a client error
, że wszystkie przykłady podane w tym akapicie są naruszeniem protokołu HTTP, a nie błędami logicznymi: składnią, ramką, routingiem. Dlatego uważam, że specyfikacja HTTP nie zezwala na 400 nieudanych operacji sprawdzania poprawności na poziomie aplikacji.Zdecydowanie powinieneś podać bardziej szczegółowe wyjaśnienie w nagłówkach odpowiedzi i / lub treści (np. Z niestandardowym nagłówkiem -
X-Status-Reason: Validation failed
).źródło
HTTP/1.0 403 Form validation errors
jest najczystszym sposobem.Polecam kod statusu 422 „Podmiot nieprzetworzony” .
źródło
200,300, 400, 500 są bardzo ogólne. Jeśli chcesz ogólny, 400 jest OK.
422 jest używany przez rosnącą liczbę interfejsów API, a nawet jest używany przez Railsy po wyjęciu z pudełka.
Bez względu na to, jaki kod stanu wybierzesz dla swojego interfejsu API, ktoś się nie zgodzi. Ale wolę 422, ponieważ „400 + status tekstowy” uważam za zbyt ogólny. Ponadto nie korzystasz z parsera zgodnego z JSON; przeciwnie, 422 z odpowiedzią JSON jest bardzo wyraźny i można przekazać wiele informacji o błędach.
Mówiąc o odpowiedzi JSON, mam tendencję do standaryzacji odpowiedzi na błąd Railsów w tym przypadku, która jest:
Ten format jest idealny do sprawdzania poprawności formularza, który uważam za najbardziej skomplikowany 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 potrzeby związane z raportowaniem błędów.
źródło
arg1
jest poprawny iarg2
prawidłowy, ale połączenie tych dwóch z przesłanymi konkretnymi wartościami jest nieprawidłowe.200
Ugh ... (309, 400, 403, 409, 415, 422) ... wiele odpowiedzi próbuje zgadnąć, argumentować i ustandaryzować najlepszy kod powrotu dla udanego żądania HTTP, ale nieudane wywołanie REST .
Jest źle mieszać kody stanu HTTP i kody stanu spoczynku.
Widziałem jednak wiele implementacji mieszających je i wielu programistów może się ze mną nie zgodzić.
Kody zwrotne HTTP są powiązane z samym
HTTP Request
sobą. Wywołanie REST jest wykonywane przy użyciu żądania protokołu przesyłania hipertekstu i działa na niższym poziomie niż sama wywołana metoda REST. REST jest koncepcją / podejściem, a jego wynik jest wynikiem biznesowym / logicznym , podczas gdy kod wyniku HTTP to transportowym .Na przykład zwracanie „404 Nie znaleziono”, gdy dzwonisz / users /, jest mylące, ponieważ może to oznaczać:
„403 Zabroniony / Odmowa dostępu” może oznaczać:
Lista może być kontynuowana z błędem „500 Server error” (błąd rzucenia HTTP Apache / Nginx lub błąd ograniczeń biznesowych w REST) lub innymi błędami HTTP itp.
Na podstawie kodu trudno zrozumieć, co było przyczyną niepowodzenia, awarii HTTP (transportu) lub awarii REST (logicznej).
Jeśli żądanie HTTP zostało fizycznie wykonane pomyślnie, zawsze powinno zwrócić kod 200, niezależnie od tego, czy rekord (y) został znaleziony, czy nie. Ponieważ zasób URI został znaleziony i był obsługiwany przez serwer HTTP. Tak, może zwrócić pusty zestaw. Czy można otrzymać pustą stronę internetową z wynikiem 200 jako HTTP, prawda?
Zamiast tego możesz zwrócić 200 kod HTTP z kilkoma opcjami:
Ponadto niektórzy dostawcy Internetu mogą przechwytywać żądania i zwracać kod 404 HTTP. Nie oznacza to, że twoich danych nie znaleziono, ale na poziomie transportu coś jest nie tak.
Z Wiki :
Dlaczego nie po prostu odpowiedzieć na coś takiego?
Google zawsze zwraca 200 jako kod stanu w interfejsie API Geokodowania, nawet jeśli żądanie logicznie się nie powiedzie: https://developers.google.com/maps/documentation/geocoding/intro#StatusCodes
Facebook zawsze zwraca 200 za pomyślne żądania HTTP, nawet jeśli żądanie REST nie powiedzie się: https://developers.facebook.com/docs/graph-api/using-graph-api/error-handling
To proste, kody stanu HTTP są dla żądań HTTP. Interfejs API REST należy do Ciebie, zdefiniuj kody stanu.
źródło
BadRequest()
ma własny model zwrotu, który będzie się różnić od zwykłego modelu zwrotu. To koszmar do przeanalizowania. @KevinHooke, zwracanie HTTP 200 z powodu błędu sprawdzania poprawności REST przypomina powiedzenie: „Otrzymałem wiadomość, odpowiedź brzmi„ nie ”i oto dlaczego. Zwracający HTTP 400 mówi: „Nie wiem o czym mówisz”.Duplikatem w bazie danych powinno być
409 CONFLICT
.Polecam używać
422 UNPROCESSABLE ENTITY
do błędów sprawdzania poprawności.Podaję tutaj dłuższe wyjaśnienie kodów 4xx .
źródło
Kod stanu 304 niezmodyfikowany również dawałby akceptowalną odpowiedź na zduplikowane żądanie. Jest to podobne do przetwarzania nagłówka
If-None-Match
przy użyciu znacznika encji.Moim zdaniem odpowiedź @ Piskvor jest bardziej oczywistym wyborem na to, co postrzegam, jest intencją pierwotnego pytania, ale mam alternatywę, która jest również istotna.
Jeśli chcesz traktować zduplikowane żądanie jako ostrzeżenie lub powiadomienie, a nie jako błąd, kod stanu odpowiedzi
304
Niezmodyfikowany iContent-Location
nagłówek identyfikujący istniejący zasób będą równie poprawne. Gdy celem jest jedynie zapewnienie istnienia zasobu, zduplikowane żądanie nie byłoby błędem, ale potwierdzeniem. Żądanie nie jest złe, ale jest po prostu nadmiarowe, a klient może odwoływać się do istniejącego zasobu.Innymi słowy, żądanie jest dobre, ale ponieważ zasób już istnieje, serwer nie musi wykonywać żadnego dalszego przetwarzania.
źródło
Adapter ActiveRecord Ember-Data oczekuje
422 UNPROCESSABLE ENTITY
na zwrot z serwera. Tak więc, jeśli twój klient jest napisany w Ember.js, powinieneś użyć 422. Tylko wtedy DS.Errors zostaną wypełnione zwracanymi błędami. Oczywiście możesz zmienić 422 na dowolny inny kod w adapterze.źródło