2010-04-22 11 views
5

Buduję RESTful magazyn danych i wykorzystuję warunkowe GET i PUT. Podczas warunkowego PUT klient może dołączyć Etag z poprzedniego GET na zasobie i jeśli obecna reprezentacja nie jest zgodna z serwerem, zwróci kod statusu HTTP 412 (Precondition Failed). Uwaga: jest to serwer/protokół oparty na procesorze Atom.Odpowiedź HTTP 412 - czy możesz dołączyć zawartość?

Moje pytanie brzmi: kiedy zwrócę stan 412, czy mogę dołączyć nową reprezentację zasobu, czy też użytkownik musi wydać nowy GET? Specyfikacja HTTP nie wydaje się powiedzieć "tak" lub "nie", tak samo jak specyfikacja Atom (chociaż ich przykład pokazuje pustą treść ciała w odpowiedzi). Wydaje się dość marnotrawstwem, aby nie zwrócić nowej reprezentacji i sprawić, że klient WYRAŻA ją. Myśli?

Odpowiedz

2

Chociaż warunkowe GET i PUT są podsumowane jako "wnioski warunkowe", są one bardzo różne koncepcyjnie. Warunkowe GET to optymalizacja wydajności i warunkowe PUTs stanowią mechanizm kontroli współbieżności. Trudno dyskutować je razem.

Na twoje pytanie dotyczące warunkowego GET: Jeśli wyślesz GET i dodasz nagłówek If-None-Match, serwer wyśle ​​200 Ok, jeśli zasób się zmienił i 304 Nie Zmodyfikowano, jeśli nie (jeśli warunek się nie powiódł) . 412 można używać tylko z warunkowymi PUT.

AKTUALIZACJA: Wygląda na to, że źle odczytałem pytanie. Do twojego punktu odnoszącego się do "odświeżenia" kopii lokalnej po nieudanym warunkowym PUT: Może się zdarzyć, że pamięć podręczna ma już najnowszą wersję i że odświeżanie GET będzie obsługiwane z pamięci podręcznej. Zwrócenie serwera przez bieżącą encję przy pomocy 412 może spowodować pogorszenie wydajności.

+0

Tak, nie podążałem za twoją początkową odpowiedzią - ale twoja uwaga odnośnie możliwej pośredniej pamięci podręcznej jest bardzo dobra. Szczerze mówiąc najlepsza odpowiedź, jaką do tej pory widziałem. – Gandalf

3

Nie, technicznie nie powinieneś. Kody błędów zazwyczaj określają, że coś poszło nie tak. Chociaż nic nie powstrzyma Cię przed zwrotem treści (i faktycznie niektóre błędy, takie jak 404 zwracają ładną stronę, która mówi, że nie znalazłeś tego, czego szukasz), celem odpowiedzi nie jest zwracanie innych treści, ale zwrócić coś, co powie ci, co było nie tak. Z technicznego punktu widzenia nie powinieneś zwracać tych danych, ponieważ zdałeś If-None-Match: etag (zakładam, że to właśnie zdałeś).

Czy naprawdę potrzebujesz zoptymalizować jeden dodatkowy http?

Im więcej o tym myślę, tym bardziej jestem przekonany, że to zły pomysł - czy zwrócisz treść na inne błędy? Semantyka PUT to PUT. Do GET należy używać semantyki GET.

+0

Optymalizacja jednego połączenia HTTP może z łatwością oznaczać miliony zapisanych żądań dziennie - więc tak, byłbym za tym.Sesje POST mają na celu POST - ale jest całkowicie poprawne, aby zwracać treść na udanym POST, więc nie zgadzam się z twoim argumentem. – Gandalf

+0

Nie robisz POST, robisz PUT. Sesje POST różnią się od obu i poprawne jest zwracanie treści do postu, ponieważ semantyka: Podstawowa różnica między żądaniami POST i PUT to odzwierciedlone w innym znaczeniu celu-celu. Identyfikator URI w żądanie POST określa zasób, który będzie obsługiwał dołączoną jednostkę . Ten zasób może być procesem przyjmowania danych, bramą do innego protokołu lub oddzielną jednostką, która akceptuje adnotacje . Oznacza to, że POST ma możliwość zwrócenia zawartości niezwiązanej z URI. – Kylar

2

Jeśli liczba dodatkowych żądań, które powstały w związku z dodatkowym żądaniem po konflikcie aktualizacji, jest na tyle znacząca, że ​​mogą wystąpić problemy z wydajnością, sugeruję, że mogą wystąpić problemy z ziarnistością zasobów.

Czy naprawdę spodziewasz się milionów razy dziennie, gdy wielu użytkowników będzie jednocześnie edytować ten sam zasób? Być może musisz przechowywać zmiany delta w zasobie zamiast aktualizować bezpośrednio zasób. Jeśli naprawdę jest tak wiele rywalizacji o te zasoby, to nie użytkownicy będą ciągle pracować nad nieaktualnymi danymi.

Jeśli twój problem polegał na tym, że twój zasób zawiera datę ostatniej modyfikacji i ostatnio zmodyfikowanego użytkownika i musiałeś wykonać GET po każdym PUT, byłbym bardziej przekonany o potrzebie przekręcenia reguł.

Jednak myślę, że wydajność dodatkowego żądania jest warta jasności dla dewelopera klienta.

Powiązane problemy