Dlaczego HTTP PUT nie może wykonywać częściowych aktualizacji w REST API?

Kto powiedział, że RESTful API musi obsługiwać częściowe aktualizacje oddzielnie przez HTTP PATCH?

Wydaje się, że nie ma żadnych korzyści. Dodaje więcej pracy do wdrożenia po stronie serwera i więcej logiki po stronie klienta, aby zdecydować, jakiego rodzaju aktualizacji zażądać.

Zadaję to pytanie w kontekście tworzenia REST API z HTTP, które dostarcza abstrakcji do znanych modeli danych. Wymaganie patcha dla częściowych aktualizacji w przeciwieństwie do PUT dla pełnych lub częściowych nie ma żadnej korzyści, ale można mnie przekonać.

Related

Http://restcookbook.com/HTTP%20Methods/idempotency/ - oznacza to, że nie masz kontroli nad oprogramowaniem serwera, które może buforować żądania.

Jakie jest uzasadnienie odmowy częściowego wprowadzenia? - brak jasnej odpowiedzi, tylko odniesienie do tego, co definiuje HTTP dla PUt vs PATCH.

Http://groups.yahoo.com/neo/groups/rest-discuss/conversations/topics/17415 - pokazuje podział myśli na ten temat.

Author: Community, 2013-11-01

3 answers

Kto tak mówi? Gość, który wynalazł odpoczynek mówi:

@mnot Oy, tak, PATCH był czymś, co stworzyłem na wstępną propozycję HTTP/1.1, ponieważ partial PUT nigdy nie jest RESTful. ;-)

Https://twitter.com/fielding/status/275471320685367296

Po pierwsze, REST jest stylem architektonicznym, a jedną z jego zasad jest wykorzystanie standaryzowanego zachowania protokołu będącego jego podstawą, więc jeśli chcesz zaimplementować RESTful API przez HTTP, musisz postępuj zgodnie z HTTP, aby był spokojny. Możesz tego nie robić, jeśli uważasz, że nie jest to odpowiednie dla Twoich potrzeb, nikt cię za to nie przeklina, ale wtedy nie odpoczywasz. Będziesz musiał udokumentować, gdzie i w jaki sposób odbiegasz od standardu, tworząc silne połączenie między implementacjami klienta i serwera, a całym celem korzystania z REST jest właśnie unikanie tego i skupienie się na typach multimediów.

Tak więc, w oparciu o RFC 7231, PUT powinien być używany tylko do całkowitego zastąpienia reprezentacja, w operacji idempotentnej. Łata powinna być używana do częściowych aktualizacji, które nie muszą być idempotentne, ale dobrze jest uczynić je idempotentnymi, wymagając warunku wstępnego lub walidacji bieżącego stanu przed zastosowaniem różnicowania. Jeśli chcesz zrobić nie idempotentne aktualizacje, częściowe lub nie, użyj POST. Proste. Wszyscy korzystający z twojego API, którzy wiedzą, jak działa PUT and PATCH, oczekują, że będą działać w ten sposób, a ty nie musisz dokumentować ani wyjaśniać, co metody powinny robić dla danego zasoby. Możesz zrobić PUT act w dowolny inny sposób, który uznasz za odpowiedni, ale wtedy będziesz musiał udokumentować to dla swoich klientów i będziesz musiał znaleźć inne hasło dla swojego API, ponieważ nie jest to RESTful.

Pamiętaj, że REST to styl architektoniczny skupiony na długofalowej ewolucji twojego API. Aby zrobić to dobrze , doda teraz więcej pracy, ale później zmiany będą łatwiejsze i mniej traumatyczne. To nie znaczy, że odpoczynek jest odpowiedni dla wszystkiego i wszystkich. Jeśli skupiasz się na łatwość wdrożenia i krótkotrwałe użytkowanie, po prostu używaj metod, jak chcesz. Możesz zrobić wszystko przez POST, jeśli nie chcesz zawracać sobie głowy wyborem właściwych metod przez klientów.

 68
Author: Pedro Werneck,
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
2015-04-15 19:36:33

Aby rozszerzyć na istniejącą odpowiedź, PUT ma wykonać pełną aktualizację (nadpisanie) stanu zasobu tylko dlatego, że HTTP definiuje metodę w ten sposób. [12]}oryginalny RFC 2616 o HTTP/1.1 nie jest zbyt jasny na ten temat, RFC 7231 dodaje wyjaśnienia semantyczne:

4.3.4 PUT

Metoda PUT wymaga utworzenia lub zastąpienia stanu zasobu docelowego stanem zdefiniowanym przez reprezentacja zawarta w treści komunikatu żądania. Pomyślne umieszczenie danej reprezentacji sugerowałoby, że kolejne GET na tym samym zasobie docelowym spowoduje wysłanie równoważnej reprezentacji w odpowiedzi 200 (OK).

Jak stwierdzono w drugiej odpowiedzi, przestrzeganie tej konwencji upraszcza zrozumienie i użycie interfejsów API i nie ma potrzeby wyraźnego dokumentowania zachowania metody PUT.


Jednak częściowe aktualizacje są nie wykluczone z powodu idempotencji. uważam to za Ważne do podkreślenia, ponieważ pojęcia te są często mylone, nawet w wielu odpowiedziach Stoskoverflow (np. tutaj ).

Idempotent oznacza wyłącznie, że zastosowanie żądania jeden lub wiele razy skutkuje tym samym efektem na serwerze. Jeszcze raz cytuję RFC 7231:

4.2.2 metody Idempotentne

Metoda żądania jest uważana za "idempotentną", jeśli zamierzony efekt na serwerze wiele identycznych żądań z tą metodą jest takie same jak efekt dla jednego takiego żądania.

Tak długo, jak częściowa aktualizacja zawiera tylko nowe wartości stanu zasobu i nie zależy od poprzednich wartości (tzn. wartości te są nadpisane), wymóg idempotencji jest spełniony. Niezależnie od tego, ile razy taka częściowa aktualizacja zostanie zastosowana, stan serwera zawsze będzie zawierał wartości określone w żądaniu.

Czy wniosek pośredni z inny klient może zmienić inną część zasobu, ponieważ idempotency odnosi się do operacji (tj. metody PUT), a nie do samego stanu. A jeśli chodzi o działanie aktualizacji nadpisywania częściowego, jej zastosowanie daje taki sam efekt po zastosowaniu raz lub wiele razy.

Przeciwnie, operacja, która nie jest idempotentna, zależy od aktualnego stanu serwera, dlatego prowadzi do różnych wyników w zależności od tego, ile razy jest wykonywany. Najprostszym przykładem na to jest zwiększanie liczby (nie-idempotentnej) zamiast ustawiania jej na wartość bezwzględną (idempotentnej).

Dla Nie idempotentnych zmian, HTTP przewiduje metody POST i PATCH, podczas gdy PATCH jest jawnie zaprojektowany do przenoszenia modyfikacji do istniejącego zasobu, podczas gdy POST może być interpretowany znacznie swobodniej w odniesieniu do relacji URI żądania, zawartości ciała i skutków ubocznych na serwerze.


Co to oznacza w praktyce? REST jest paradygmatem implementacji API za pośrednictwem protokołu HTTP - konwencja, którą wiele osób uznało za rozsądną i dlatego prawdopodobnie zostanie przyjęta lub zrozumiana. Mimo to istnieją kontrowersje dotyczące tego, co jest RESTful, a co nie, ale nawet pomijając te kwestie, REST nie jest jedynym poprawnym lub znaczącym sposobem budowania interfejsów API HTTP.

[9]}sam protokół HTTP nakłada ograniczenia na to, co możesz, a czego nie, a wiele z nich ma rzeczywisty praktyczny wpływ. Na przykład, lekceważenie idempotencji może spowodować, że serwery cache zmienią liczbę żądań faktycznie wydanych przez Klienta, a następnie zakłócą logikę oczekiwaną przez aplikacje. Ważne jest zatem, aby zdawać sobie sprawę z konsekwencji, gdy odbiegają od normy.

Będąc ściśle zgodny z odpoczynkiem, nie ma całkowicie satysfakcjonującego rozwiązania dla częściowych aktualizacji (niektórzy nawet mówią, że sama potrzeba jest przeciwko odpoczynkowi). Problem w tym, że PATCH, które wydaje się być wykonane tylko w tym celu, jest nie idempotentny. Tak więc, używając {[3] } dla częściowych aktualizacji idempotencji, tracisz zalety idempotencji (dowolna liczba automatycznych powtórzeń, prostsza logika, potencjał optymalizacji w kliencie, serwerze i sieci). W związku z tym możesz zadać sobie pytanie, czy używanie PUT jest naprawdę najgorszym pomysłem, o ile zachowanie jest wyraźnie udokumentowane i nie psuje się, ponieważ użytkownicy (i pośrednie węzły sieciowe) polegają na pewnym zachowaniu...?

 13
Author: TheOperator,
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
2020-06-20 09:12:55

Częściowe aktualizacje są dozwolone przez PUT (zgodnie z RFC 7231 http://tools.ietf.org/html/rfc7231#section-4.3.4).

",... Żądanie PUT jest definiowane jako zastąpienie stanu zasobu docelowego."- Zamiana części obiektu w zasadzie zmienia jego stan.

" częściowe aktualizacje zawartości są możliwe poprzez ukierunkowanie na odrębnie zidentyfikowany zasób ze stanem, który pokrywa się z częścią większego zasobu ..."

Zgodnie z tym RFC następne żądanie jest ważne: PUT/resource / 123 {name: 'new name'} Zmieni tylko nazwę dla określonego zasobu. Podanie id wewnątrz ładunku żądania byłoby niepoprawne (jak PUT nie zezwala na częściowe aktualizacje dla nieokreślonych zasobów).

PS: Poniżej znajduje się przykład, kiedy PATCH jest przydatny.

Istnieje obiekt, który ma tablicę w środku. Za pomocą PUT nie można zaktualizować określonej wartości. Możesz tylko zastąpić całą listę na nową. Za pomocą patcha można zamienić jedną wartość na inną. Z mapami i bardziej złożonymi obiektami korzyści będą jeszcze większe.

 -4
Author: Konstantin Petrukhnov,
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-08-22 08:12:26