Zastanawiałem się nad tym.
Załóżmy, że mam user
zasób id
i name
polami. Jeśli chcę zaktualizować pole, mogę po prostu wysłać PATCH do takiego zasobu
PATCH /users/42
{"name": "john doe"}
A następnie aplikacja zaktualizuje nazwę użytkownika 42.
Ale dlaczego, jeśli powtórzę tę prośbę, wynik byłby inny?
Zgodnie z RFC 5789
PATCH nie jest bezpieczny ani idempotentny
rest
api-design
http
web-api
mattecapu
źródło
źródło
{"name": "bendjamin franklin"}
Odpowiedzi:
Żądanie PATCH może być idempotentne, ale nie jest to wymagane. Z tego powodu określa się go jako niestosowny.
To, czy PATCH może być idempotentny, zależy od tego, w jaki sposób przekazywane są wymagane zmiany.
Na przykład, jeśli format poprawki ma postać
{change: 'Name' from: 'benjamin franklin' to: 'john doe'}
, to każde żądanie PATCH po pierwszym będzie miało inny efekt (odpowiedź na błąd) niż pierwsze żądanie.Innym powodem braku idempotencji może być to, że zastosowanie modyfikacji do czegoś innego niż oryginalny zasób może spowodować, że zasób będzie nieważny. Tak byłoby również w przypadku wielokrotnego zastosowania zmiany.
źródło
<name>
element. Jeśli PATCH doda<name>
element do zasobu, który pierwotnie go nie zawierał, wówczas zastosowanie PATCH dwukrotnie (lub zastosowanie go do zasobu, który już zawiera a<name>
) powoduje, że zasób jest nieprawidłowy, ponieważ nagle zawierałby dwa<name>
elementy, co jest niedozwolone dla takich zasobów.Myślę, że jasną odpowiedzią, gdy PATCH nie jest idempotentny, jest ten akapit z RFC 5789:
Ponieważ RFC określa, że łatka zawiera pewne „ogólne zmiany” w zasobie, powinniśmy wyjść poza zwykłą zamianę pola. Jeśli zasób jest przeznaczony dla licznika, łata może zażądać jego przyrostu, co oczywiście nie jest idempotet.
źródło
PATCH
żądania opisują zestaw operacji, które mają być zastosowane do zasobu, jeśli zastosujesz ten sam zestaw operacji dwa razy do tego samego zasobu, wynik może być inny. Jest tak, ponieważ definiowanie operacji zależy od Ciebie. Innymi słowy, musisz zdefiniować reguły łączenia .Pamiętaj, że
PATCH
prośba może być wykorzystana do łatania zasobów w wielu różnych formatach, nie tylko w JSON.Dlatego
PATCH
żądanie może być idempotentne, jeśli zdefiniujesz reguły scalania jako idempotentne .Idempotentny przykład:
Przykład nie idempotentny:
W drugim przykładzie użyłem składni „Mongo like”, którą zrekompensowałem do zwiększenia atrybutu. Oczywiście nie jest to idempotentne, ponieważ wielokrotne wysyłanie tego samego żądania spowodowałoby za każdym razem inne wyniki.
Teraz możesz się zastanawiać, czy użycie takiej wymyślonej składni jest prawidłowe. Zgodnie ze standardami jest to:
Być może zastanawiasz się również, czy korzystanie z żądań w ten sposób jest spokojne
PATCH
, a wiele osób uważa, że tak nie jest, oto dobra odpowiedź z dużą ilością komentarzy na ten temat.źródło