Kod stanu HTTP dla częściowo udanego żądania

115

Mam aplikację, która wysyła wiadomości do użytkowników. W żądaniu pocztowym przesyłany jest ciąg XML zawierający wszystkich użytkowników, którzy powinni otrzymać tę konkretną wiadomość. Jeśli któryś z użytkowników na liście nie istnieje, oddaję listę brakujących użytkowników z powrotem do klienta do dalszej oceny.

Teraz zadaję sobie pytanie, jaki byłby prawidłowy kod statusu dla aplikacji, mówiąc, że żądanie zostało zaakceptowane, ale są rzeczy, których nie można zrobić.

Problemu można by uniknąć, gdyby nie pozwolono na umieszczenie brakujących użytkowników na liście. Wtedy przy próbie wysłania wystąpiłby błąd 4xx. Jednak tworzenie API w ten sposób nie ma sensu. Z drugiej strony mógłbym uznać, że warunek błędu dotyczy wyłącznie aplikacji. Ale wysłanie 200 po prostu nie wydaje się właściwe. Byłoby miło dać klientowi wskazówkę, kiedy dokładnie przyjrzeć się odpowiedzi błędu. np. aby uniknąć ciągłego wysyłania wiadomości do tych użytkowników

Norbert Hartl
źródło

Odpowiedzi:

66

Miałem do czynienia z bardzo podobnym problemem. W tym przypadku zwróciłem plik

207 Multi-Status

To nie jest ścisły protokół HTTP, to część rozszerzenia WebDAV, więc jeśli nie masz kontroli nad klientem, to nie jest to dla ciebie dobre. Jeśli tak, możesz zrobić coś takiego:

   <?xml version="1.0" encoding="utf-8" ?>
   <D:multistatus xmlns:D='DAV:'>
     <D:response>
       <D:user>user-123</D:user>
       <D:status>success</D:status>
     </D:response>
     <D:response>
       <D:user>user-789</D:user>
       <D:status>failure</D:status>
     </D:response>
   </D:multistatus>

Ale znowu jest to rozszerzenie HTTP i musisz mieć również kontrolę nad klientem.

Kylar
źródło
3
Myślałem o tym, ale nie czułem się z tym dobrze. Dzięki!
Norbert Hartl
Zaletą jest to, że możesz zwrócić dowolną liczbę lub mało istotnych danych, co jest przydatne, co jest szczególnie przydatne w przypadku zestawów danych mieszanych, tj. Gdy niektóre zawodzą, a inne przechodzą.
Kylar
Rozumiem. Po prostu próbuję uniknąć dodatkowego poziomu obsługi statusu (co nie jest miłym IMHO). Większość mojego kodu działa z kodami HTTP. I myślę, że mój opisany przypadek użycia poradzi sobie bez.
Norbert Hartl
Zawsze możesz odesłać treść - wyślij 200 z odpowiedzią JSON lub cokolwiek chcesz, aby określić, które z nich się powiodły.
Kylar
Tak, wiem. Ale jeśli zwrócisz ciało, musisz je przeanalizować. I w tym momencie wprowadzasz drugą warstwę obsługi logiki aplikacji. To zwiększa złożoność i potrzebujesz dobrego powodu, aby to zrobić.
Norbert Hartl
65

Miałem ten sam problem i ostatecznie użyłem dwóch różnych rozwiązań:

  • Kod powrotu HTTP 202: Accepted, wskazujący, że żądanie było prawidłowe, ale nie ma gwarancji, że wszystko poszło tak, jak powinno.
  • Zwróć normę 200w odpowiedzi, ale dołącz listę rzeczy, które nie wyszły w treści odpowiedzi.

Drugi zwykle działa najlepiej, ale pierwszy jest świetny, jeśli jesteś leniwy lub używasz kolejki do przetwarzania.

Arne
źródło
5
Czy 202 nie odnosi się bardziej do czegoś takiego jak kolejkowanie?
Sinaesthetic
6
Tak, @Sinaesthetic. Z najnowszej specyfikacji HTTP 1.1 wynika, że ​​„(...) żądanie zostało zaakceptowane do przetwarzania, ale przetwarzanie nie zostało zakończone”. Zatem dla częściowego sukcesu 202 nie jest właściwe.
Huercio
-4

A co z używaniem 206 Częściowych treści. Wiem, że 206 jest bardziej o zakresach, ale co, jeśli mogłoby to wskazywać na częściowo pomyślne żądanie?

Yusuf
źródło
MDN stwierdza, co następuje: „Kod odpowiedzi statusu pomyślnej zawartości częściowej HTTP 206 wskazuje, że żądanie powiodło się i że treść zawiera żądane zakresy danych, zgodnie z opisem w nagłówku Range żądania”. O ile rozumiem, 206 Partial Content dotyczy wyłącznie żądań z zakresem treści.
sbbs
-14

HyperText Transfer Protocol zajmuje się stroną transmisyjną rzeczy. Nie ma kodów błędów do obsługi błędów na poziomie aplikacji.

Zwrócenie 200 jest tutaj właściwą rzeczą. Jeśli chodzi o HTTP, żądanie zostało poprawnie odebrane, poprawnie obsłużone, a Ty odsyłasz odpowiedź. Tak więc na poziomie HTTP wszystko jest w porządku. Wszelkie błędy lub ostrzeżenia związane z aplikacją działającą na górze http powinny znajdować się w odpowiedzi. Pozwoli to również uniknąć nieprzyjemnych problemów, które możesz napotkać na serwerach proxy, które mogą nie obsługiwać niektórych odpowiedzi w oczekiwany sposób.

AVee
źródło
18
HTTP to protokół na poziomie aplikacji. Nie można tego po prostu umieścić na poziomie transportu i aplikacji. Jeśli myślisz o OSI, to HTTP znajduje się w warstwach 5-7. HTTP jest nieco inny. Większość nagłówków i kodów powrotnych jest rzeczywiście specyficzna dla aplikacji. Kody zależą tylko od informacji podanych w jednostkach protokołu HTTP, a nie od niestandardowych formatów aplikacji. Odnośnie 200 powiedziałbym, że twoja definicja jest całkowicie błędna, jeśli stosuje się ją do czasowników nie będących POST. Ale POST trochę zmienia grę iw tym kontekście twoje założenie "obsługiwane poprawnie" też nie jest pewne
Norbert Hartl
Mówiąc ściślej, OSI uważa HTTP za protokół na poziomie aplikacji i podczas rozmowy z „normalnym” serwerem internetowym jest to prawdą. Ale w twoim przypadku korzystasz z własnego protokołu ponad HTTP, tak jak robi to obecnie wiele aplikacji. W tego typu zastosowaniach HTTP zapewnia tylko transport. (Twoja aplikacja wysyła wiadomości do użytkowników, nie przenosi hipertekstu ...)
AVee
2
Żeby było jasne. HTTP w sposób REST jest skoncentrowany na zasobach. W tym kontekście 200 oznacza tożsamość (wskazany zasób) zamiast 3xx, które wskazuje kierunek tożsamości. Użycie POST zamienia identyfikator URI zasobu w identyfikator URI przetwarzania, a kody błędów muszą sobie z tym poradzić. Kontekst trochę się zmienia, a definicja rzeczy staje się nieco niewyraźna lub przynajmniej trudna do zrozumienia
Norbert Hartl
1
Przesunięcie kontekstu oznacza również, że nie ma odpowiednich kodów błędów, ponieważ protokół nigdy nie był projektowany z myślą o tym kontekście ;-) Myślę również, że należy zachować ostrożność przy używaniu kodów błędów, ponieważ serwery proxy zwykle działają z nimi, zastępując odpowiedź niestandardowa strona błędu, może to być prawdziwy PITA.
AVee
1
W każdym razie dziękuję za odpowiedź na moje pytanie. Właśnie odkryłem, że stackoverflow jest złym klientem czatu :)
Norbert Hartl