Zunächst einige Definitionen:
PUT ist in Abschnitt 9.6 RFC 2616 definiert :
Die PUT-Methode fordert an, dass die eingeschlossene Entität unter dem angegebenen Anforderungs-URI gespeichert wird. Wenn sich der Anforderungs-URI auf eine bereits vorhandene Ressource bezieht, MUSS die eingeschlossene Entität als modifizierte Version der auf dem Ursprungsserver befindlichen Entität betrachtet werden . Wenn der Anforderungs-URI nicht auf eine vorhandene Ressource verweist und dieser URI vom anfordernden Benutzeragenten als neue Ressource definiert werden kann, kann der Ursprungsserver die Ressource mit diesem URI erstellen.
PATCH ist in RFC 5789 definiert :
Die PATCH-Methode fordert an, dass eine Reihe von Änderungen, die in der Anforderungsentität beschrieben sind, auf die durch den Anforderungs-URI identifizierte Ressource angewendet werden.
Auch gemäß RFC 2616 ist Abschnitt 9.1.2 PUT nicht korrekt, PATCH nicht.
Schauen wir uns nun ein reales Beispiel an. Wenn ich /users
mit den Daten POST mache {username: 'skwee357', email: '[email protected]'}
und der Server in der Lage ist, eine Ressource zu erstellen, antwortet er mit 201 und dem Ressourcenstandort (nehmen wir an /users/1
) und jeder nächste Aufruf von GET /users/1
wird zurückgegeben {id: 1, username: 'skwee357', email: '[email protected]'}
.
Angenommen, ich möchte meine E-Mail-Adresse ändern. E-Mail-Änderungen werden als "eine Reihe von Änderungen" betrachtet und daher sollte ich /users/1
mit " Patch-Dokument " PATCHEN . In meinem Fall wäre es das JSON-Dokument : {email: '[email protected]'}
. Der Server gibt dann 200 zurück (vorausgesetzt, die Berechtigung ist in Ordnung). Dies bringt mich zur ersten Frage:
- PATCH ist NICHT idempotent. Dies wurde in RFC 2616 und RFC 5789 angegeben. Wenn ich jedoch dieselbe PATCH-Anforderung (mit meiner neuen E-Mail) ausstelle, erhalte ich denselben Ressourcenstatus (wobei meine E-Mail auf den angeforderten Wert geändert wird). Warum ist PATCH dann nicht idempotent?
PATCH ist ein relativ neues Verb (RFC wurde im März 2010 eingeführt) und löst das Problem des "Pattens" oder Modifizierens einer Reihe von Feldern. Vor der Einführung von PATCH verwendeten alle PUT, um Ressourcen zu aktualisieren. Aber nachdem PATCH eingeführt wurde, bin ich verwirrt darüber, wofür PUT verwendet wird. Und das bringt mich zu meiner zweiten (und der Haupt-) Frage:
- Was ist der wahre Unterschied zwischen PUT und PATCH? Ich habe irgendwo gelesen, dass PUT verwendet werden könnte, um die gesamte Entität unter einer bestimmten Ressource zu ersetzen , daher sollte man die vollständige Entität senden (anstelle von Attributen wie bei PATCH). Was ist die wirkliche praktische Verwendung für einen solchen Fall? Wann möchten Sie eine Entität an einem bestimmten Ressourcen-URI ersetzen / überschreiben und warum wird eine solche Operation nicht als Aktualisierung / Patching der Entität angesehen? Der einzige praktische Anwendungsfall, den ich für PUT sehe, ist die Ausgabe eines PUT für eine Sammlung, dh
/users
das Ersetzen der gesamten Sammlung. Die Ausgabe von PUT für eine bestimmte Entität ist nach Einführung von PATCH nicht sinnvoll. Liege ich falsch?
Antworten:
HINWEIS : Als ich zum ersten Mal über REST gelesen habe, war Idempotenz ein verwirrendes Konzept, um zu versuchen, es richtig zu machen. Ich habe es in meiner ursprünglichen Antwort immer noch nicht ganz richtig verstanden, wie weitere Kommentare (und die Antwort von Jason Hoetger ) gezeigt haben. Für eine Weile habe ich mich geweigert, diese Antwort ausgiebig zu aktualisieren, um Jason nicht effektiv zu plagiieren, aber ich bearbeite sie jetzt, weil ich darum gebeten wurde (in den Kommentaren).
Nachdem Sie meine Antwort gelesen haben, schlage ich vor, dass Sie auch die ausgezeichnete Antwort von Jason Hoetger auf diese Frage lesen , und ich werde versuchen, meine Antwort zu verbessern, ohne einfach von Jason zu stehlen.
Warum ist PUT idempotent?
Wie Sie in Ihrem RFC 2616-Zitat festgestellt haben, wird PUT als idempotent angesehen. Wenn Sie eine Ressource platzieren, spielen diese beiden Annahmen eine Rolle:
Sie beziehen sich auf eine Entität, nicht auf eine Sammlung.
Die von Ihnen bereitgestellte Entität ist vollständig (die gesamte Entität).
Schauen wir uns eines Ihrer Beispiele an.
Wenn Sie dieses Dokument wie vorgeschlagen an POST
/users
senden, erhalten Sie möglicherweise eine Entität wie zWenn Sie diese Entität später ändern möchten, wählen Sie zwischen PUT und PATCH. Ein PUT könnte folgendermaßen aussehen:
Sie können dasselbe mit PATCH erreichen. Das könnte so aussehen:
Sie werden sofort einen Unterschied zwischen diesen beiden bemerken. Der PUT enthielt alle Parameter dieses Benutzers, aber PATCH enthielt nur den Parameter, der geändert wurde (
email
).Wenn PUT verwendet wird , wird angenommen , dass Sie die komplette Einheit senden, und dass eine vollständige Einheit ersetzt zu dieser URI jede bestehende Einheit. Im obigen Beispiel erreichen PUT und PATCH dasselbe Ziel: Beide ändern die E-Mail-Adresse dieses Benutzers. PUT ersetzt dies jedoch, indem die gesamte Entität ersetzt wird, während PATCH nur die bereitgestellten Felder aktualisiert und die anderen in Ruhe lässt.
Da PUT-Anforderungen die gesamte Entität umfassen, sollte sie, wenn Sie dieselbe Anforderung wiederholt ausgeben, immer das gleiche Ergebnis haben (die von Ihnen gesendeten Daten sind jetzt die gesamten Daten der Entität). Daher ist PUT idempotent.
PUT falsch verwenden
Was passiert, wenn Sie die oben genannten PATCH-Daten in einer PUT-Anforderung verwenden?
(Ich gehe für die Zwecke dieser Frage davon aus, dass der Server keine spezifischen erforderlichen Felder hat und dies zulassen würde ... dies ist in der Realität möglicherweise nicht der Fall.)
Da wir PUT verwendet haben, aber nur geliefert
email
haben, ist dies das einzige in dieser Entität. Dies hat zu Datenverlust geführt.Dieses Beispiel dient nur zur Veranschaulichung. Tun Sie dies niemals. Diese PUT-Anfrage ist technisch idempotent, aber das bedeutet nicht, dass es keine schreckliche, kaputte Idee ist.
Wie kann PATCH idempotent sein?
In dem obigen Beispiel PATCH war idempotent. Sie haben eine Änderung vorgenommen, aber wenn Sie dieselbe Änderung immer wieder vorgenommen haben, wird immer das gleiche Ergebnis zurückgegeben: Sie haben die E-Mail-Adresse auf den neuen Wert geändert.
Mein ursprüngliches Beispiel, aus Gründen der Genauigkeit korrigiert
Ich hatte ursprünglich Beispiele, von denen ich dachte, dass sie keine Idempotenz zeigen, aber sie waren irreführend / falsch. Ich werde die Beispiele beibehalten, sie jedoch verwenden, um eine andere Sache zu veranschaulichen: Mehrere PATCH-Dokumente für dieselbe Entität, die unterschiedliche Attribute ändern, machen die PATCHes nicht nicht idempotent.
Nehmen wir an, dass zu einem früheren Zeitpunkt ein Benutzer hinzugefügt wurde. Dies ist der Zustand, von dem aus Sie beginnen.
Nach einem PATCH haben Sie eine geänderte Entität:
Wenn Sie Ihren PATCH dann wiederholt anwenden, erhalten Sie weiterhin das gleiche Ergebnis: Die E-Mail wurde auf den neuen Wert geändert. A geht rein, A kommt raus, deshalb ist das idempotent.
Eine Stunde später, nachdem Sie Kaffee gemacht und eine Pause gemacht haben, kommt jemand anderes mit seinem eigenen PATCH. Es scheint, dass die Post einige Änderungen vorgenommen hat.
Da sich dieser PATCH von der Post nicht mit E-Mails befasst, sondern nur mit der Postleitzahl, wird bei wiederholter Anwendung auch das gleiche Ergebnis erzielt: Die Postleitzahl wird auf den neuen Wert gesetzt. A geht rein, A kommt raus, deshalb ist das auch so idempotent.
Am nächsten Tag beschließen Sie, Ihren PATCH erneut zu senden.
Ihr Patch hat den gleichen Effekt wie gestern: Er hat die E-Mail-Adresse festgelegt. A ging hinein, A kam heraus, daher ist dies auch idempotent.
Was ich in meiner ursprünglichen Antwort falsch verstanden habe
Ich möchte eine wichtige Unterscheidung treffen (etwas, das ich in meiner ursprünglichen Antwort falsch verstanden habe). Viele Server antworten auf Ihre REST-Anforderungen, indem sie den neuen Entitätsstatus mit Ihren Änderungen (falls vorhanden) zurücksenden. Wenn Sie diese Antwort zurückerhalten, unterscheidet sie sich von der Antwort , die Sie gestern erhalten haben , da die Postleitzahl nicht die ist, die Sie zuletzt erhalten haben. Ihre Anfrage betraf jedoch nicht die Postleitzahl, sondern nur die E-Mail. Ihr PATCH-Dokument ist also immer noch idempotent - die E-Mail, die Sie in PATCH gesendet haben, ist jetzt die E-Mail-Adresse der Entität.
Wann ist PATCH also nicht idempotent?
Für eine vollständige Behandlung dieser Frage verweise ich Sie erneut auf die Antwort von Jason Hoetger . Ich werde es dabei belassen, weil ich ehrlich gesagt nicht glaube, dass ich diesen Teil besser beantworten kann als er es bereits getan hat.
quelle
GET /users/1
vor der Aktualisierung der PostleitzahlGET /users/1
durch die Post die gleiche Anfrage stellen und nach der Aktualisierung durch die Post erneut dieselbe Anfrage stellen würden, würden Sie zwei unterschiedliche Antworten erhalten (unterschiedliche Postleitzahlen). Das gleiche "A" (GET-Anfrage) wird eingegeben, aber Sie erhalten unterschiedliche Ergebnisse. Dennoch ist GET immer noch idempotent.Obwohl Dan Lowes ausgezeichnete Antwort die Frage des OP nach dem Unterschied zwischen PUT und PATCH sehr gründlich beantwortete, ist seine Antwort auf die Frage, warum PATCH nicht idempotent ist, nicht ganz richtig.
Um zu zeigen, warum PATCH nicht idempotent ist, hilft es, mit der Definition von Idempotenz zu beginnen (aus Wikipedia ):
In einer zugänglicheren Sprache könnte ein idempotenter PATCH wie folgt definiert werden: Nach dem PATCHEN einer Ressource mit einem Patchdokument ändern alle nachfolgenden PATCH-Aufrufe derselben Ressource mit demselben Patchdokument die Ressource nicht.
Umgekehrt ist eine nicht idempotente Operation eine Operation mit f (f (x))! = F (x), die für PATCH wie folgt angegeben werden könnte: Nach dem PATCHEN einer Ressource mit einem Patch-Dokument ruft nachfolgender PATCH dieselbe Ressource mit dem auf gleiches Patch - Dokument macht die Ressource ändern.
Um einen nicht-idempotenten PATCH zu veranschaulichen, nehmen wir an, dass eine / users-Ressource vorhanden ist, und nehmen wir an, dass der Aufruf
GET /users
eine Liste von Benutzern zurückgibt, derzeit:Angenommen, der Server erlaubt PATCHing / users anstelle von PATCHing / users / {id}, wie im Beispiel des OP. Lassen Sie uns diese PATCH-Anfrage stellen:
Unser Patch-Dokument weist den Server an, einen neuen Benutzer
newuser
zur Liste der Benutzer hinzuzufügen . Nach dem ersten AufrufGET /users
würde zurückkehren:Was passiert nun, wenn wir genau dieselbe PATCH-Anforderung wie oben ausgeben? (In diesem Beispiel nehmen wir an, dass die Ressource / users doppelte Benutzernamen zulässt.) Das "op" ist "add", sodass ein neuer Benutzer zur Liste hinzugefügt wird und ein nachfolgender Benutzer Folgendes
GET /users
zurückgibt:Die Ressource / users hat sich erneut geändert , obwohl wir genau denselben PATCH für genau denselben Endpunkt ausgegeben haben . Wenn unser PATCH f (x) ist, ist f (f (x)) nicht dasselbe wie f (x), und daher ist dieser bestimmte PATCH nicht idempotent .
Obwohl PATCH nicht garantiert idempotent ist, enthält die PATCH-Spezifikation nichts, was Sie daran hindert, alle PATCH-Vorgänge auf Ihrem bestimmten Server idempotent auszuführen. RFC 5789 erwartet sogar Vorteile von idempotenten PATCH-Anforderungen:
In Dans Beispiel ist seine PATCH-Operation tatsächlich idempotent. In diesem Beispiel hat sich die Entität / users / 1 zwischen unseren PATCH-Anforderungen geändert, jedoch nicht aufgrund unserer PATCH-Anforderungen. Es war tatsächlich das andere Patch-Dokument der Post, das dazu führte , dass sich die Postleitzahl änderte. Der unterschiedliche PATCH der Post ist eine andere Operation. Wenn unser PATCH f (x) ist, ist der PATCH der Post g (x). Idempotenz gibt das an
f(f(f(x))) = f(x)
, macht aber keine Garantie dafürf(g(f(x)))
.quelle
/users
, würde dies PUT ebenfalls nicht idempotent machen. Alles hängt davon ab, wie der Server für die Verarbeitung von Anforderungen ausgelegt ist./users
), sollte jede PUT-Anforderung den Inhalt dieser Sammlung ersetzen. Ein PUT/users
sollte also eine Sammlung von Benutzern erwarten und alle anderen löschen. Das ist idempotent. Es ist unwahrscheinlich, dass Sie so etwas auf einem / users-Endpunkt tun. Aber so etwas/users/1/emails
kann eine Sammlung sein und es kann durchaus gültig sein, die gesamte Sammlung durch eine neue zu ersetzen.op
Aktion, die eine bestimmte serverseitige Logik auslöst. Dies würde erfordern, dass Server und Client die spezifischen Werte kennen, die für dasop
Feld übergeben werden müssen, um serverseitige Workflows auszulösen. In einfacheren REST-Szenarien ist diese Art vonop
Funktionalität eine schlechte Praxis und sollte wahrscheinlich direkt über HTTP-Verben verarbeitet werden.Ich war auch neugierig und fand ein paar interessante Artikel. Ich kann Ihre Frage möglicherweise nicht in vollem Umfang beantworten, aber dies liefert zumindest einige weitere Informationen.
http://restful-api-design.readthedocs.org/en/latest/methods.html
Vor diesem Hintergrund sollte ein PUT das gesamte Objekt senden. Zum Beispiel,
Dies würde die E-Mail effektiv aktualisieren. Der Grund, warum PUT möglicherweise nicht zu effektiv ist, ist, dass Sie nur ein Feld wirklich ändern und den Benutzernamen angeben, was irgendwie nutzlos ist. Das nächste Beispiel zeigt den Unterschied.
Wenn der PUT gemäß der Spezifikation entworfen wurde, würde der PUT den Benutzernamen auf null setzen und Sie würden Folgendes zurückerhalten.
Wenn Sie einen PATCH verwenden, aktualisieren Sie nur das von Ihnen angegebene Feld und lassen den Rest wie in Ihrem Beispiel in Ruhe.
Die folgende Einstellung zum PATCH ist etwas anders als ich sie noch nie gesehen habe.
http://williamdurand.fr/2014/02/14/please-do-not-patch-like-an-idiot/
Sie behandeln den PATCH mehr oder weniger als eine Möglichkeit, ein Feld zu aktualisieren. Anstatt also über das Teilobjekt zu senden, senden Sie über die Operation. dh E-Mail durch Wert ersetzen.
Der Artikel endet damit.
Jetzt weiß ich nicht, ob ich dem Artikel besonders zustimme, wie viele Kommentatoren betonen. Das Senden über eine Teildarstellung kann leicht eine Beschreibung der Änderungen sein.
Für mich ist die Verwendung von PATCH gemischt. Zum größten Teil werde ich PUT als PATCH behandeln, da der einzige wirkliche Unterschied, den ich bisher bemerkt habe, darin besteht, dass PUT fehlende Werte auf Null setzen sollte. Es ist vielleicht nicht der 'richtigste' Weg, aber viel Glück beim Codieren.
quelle
Der Unterschied zwischen PUT und PATCH besteht darin, dass:
PATCH benötigt eine "Patch-Sprache", um dem Server mitzuteilen, wie die Ressource geändert werden soll. Der Anrufer und der Server müssen einige "Operationen" wie "Hinzufügen", "Ersetzen", "Löschen" definieren. Zum Beispiel:
Anstatt explizite "Operations" -Felder zu verwenden, kann die Patch-Sprache dies implizit machen, indem Konventionen wie die folgenden definiert werden:
im PATCH-Anforderungshauptteil:
Mit der obigen Konvention kann der PATCH im Beispiel die folgende Form annehmen:
Was prägnanter und benutzerfreundlicher aussieht. Die Benutzer müssen sich jedoch der zugrunde liegenden Konvention bewusst sein.
Mit den oben erwähnten Operationen ist der PATCH immer noch idempotent. Wenn Sie jedoch Operationen wie "Inkrementieren" oder "Anhängen" definieren, können Sie leicht erkennen, dass diese nicht mehr idempotent sind.
quelle
TLDR - Dumbed Down Version
PUT => Alle neuen Attribute für eine vorhandene Ressource festlegen.
PATCH => Eine vorhandene Ressource teilweise aktualisieren (nicht alle Attribute erforderlich).
quelle
Lassen Sie mich den Abschnitt 4.2.2 von RFC 7231 , der bereits in früheren Kommentaren zitiert wurde, genauer zitieren und kommentieren:
Was sollte also nach einer wiederholten Anforderung einer idempotenten Methode "dasselbe" sein? Nicht der Serverstatus oder die Serverantwort, sondern der beabsichtigte Effekt . Insbesondere sollte die Methode "aus Sicht des Kunden" idempotent sein. Ich denke, dieser Standpunkt zeigt, dass das letzte Beispiel in Dan Lowes Antwort , das ich hier nicht plagiieren möchte, tatsächlich zeigt, dass eine PATCH-Anfrage nicht idempotent sein kann (auf natürlichere Weise als das Beispiel in Jason Hoetgers Antwort ).
Lassen Sie uns das Beispiel etwas präziser machen, indem wir eine mögliche Absicht für den ersten Kunden explizit machen . Angenommen, dieser Client durchsucht die Liste der Benutzer mit dem Projekt, um ihre E-Mails und Postleitzahlen zu überprüfen . Er beginnt mit Benutzer 1 und bemerkt, dass die Zip richtig ist, aber die E-Mail falsch ist. Er beschließt, dies mit einer PATCH-Anfrage zu korrigieren, die völlig legitim ist und nur sendet
da dies die einzige Korrektur ist. Jetzt schlägt die Anforderung aufgrund eines Netzwerkproblems fehl und wird einige Stunden später automatisch erneut gesendet. In der Zwischenzeit hat ein anderer Client (fälschlicherweise) die Zip-Datei von Benutzer 1 geändert. Wenn Sie dann dieselbe PATCH-Anforderung ein zweites Mal senden, wird der beabsichtigte Effekt des Clients nicht erreicht, da wir eine falsche Zip-Datei erhalten. Daher ist die Methode im Sinne des RFC nicht idempotent.
Wenn der Client stattdessen eine PUT-Anforderung verwendet, um die E-Mail zu korrigieren und alle Eigenschaften von Benutzer 1 zusammen mit der E-Mail an den Server zu senden, wird seine beabsichtigte Wirkung auch dann erzielt, wenn die Anforderung später erneut gesendet werden muss und Benutzer 1 geändert wurde in der Zwischenzeit --- da die zweite PUT-Anfrage alle Änderungen seit der ersten Anfrage überschreibt.
quelle
Nach meiner bescheidenen Meinung bedeutet Idempotenz:
Ich sende eine konkurrierende Ressourcendefinition. Der resultierende Ressourcenzustand entspricht genau den Definitionen der PUT-Parameter. Jedes Mal, wenn ich die Ressource mit denselben PUT-Parametern aktualisiere, ist der resultierende Status genau der gleiche.
Ich habe nur einen Teil der Ressourcendefinition gesendet, daher kann es vorkommen, dass andere Benutzer in der Zwischenzeit die ANDEREN Parameter dieser Ressource aktualisieren. Folglich können aufeinanderfolgende Patches mit denselben Parametern und ihren Werten zu unterschiedlichen Ressourcenzuständen führen. Zum Beispiel:
Angenommen, ein Objekt ist wie folgt definiert:
AUTO: - Farbe: schwarz, - Typ: Limousine, - Sitze: 5
Ich patche es mit:
{Farbe Rot'}
Das resultierende Objekt ist:
AUTO: - Farbe: rot, - Typ: Limousine, - Sitze: 5
Dann patchen einige andere Benutzer dieses Auto mit:
{Typ: 'Schrägheck'}
Das resultierende Objekt ist also:
AUTO: - Farbe: rot, - Typ: Schrägheck, - Sitze: 5
Wenn ich dieses Objekt nun erneut patche mit:
{Farbe Rot'}
Das resultierende Objekt ist:
AUTO: - Farbe: rot, - Typ: Schrägheck, - Sitze: 5
Was unterscheidet sich von dem, was ich vorher habe?
Aus diesem Grund ist PATCH nicht idempotent, während PUT idempotent ist.
quelle
Um die Diskussion über die Idempotenz abzuschließen, sollte ich beachten, dass man Idempotenz im REST-Kontext auf zwei Arten definieren kann. Lassen Sie uns zunächst einige Dinge formalisieren:
Eine Ressource ist eine Funktion, deren Codomäne die Klasse der Zeichenfolgen ist. Mit anderen Worten, eine Ressource ist eine Teilmenge von
String × Any
, bei der alle Schlüssel eindeutig sind. Nennen wir die Klasse der RessourcenRes
.Eine REST-Operation für Ressourcen ist eine Funktion
f(x: Res, y: Res): Res
. Zwei Beispiele für REST-Operationen sind:PUT(x: Res, y: Res): Res = x
, undPATCH(x: Res, y: Res): Res
, was funktioniert wiePATCH({a: 2}, {a: 1, b: 3}) == {a: 2, b: 3}
.(Diese Definition ist speziell darüber zu streiten , entworfen
PUT
undPOST
, und beispielsweise nicht viel Sinn machen aufGET
undPOST
, da es nicht über Ausdauer schert).Jetzt durch Fixieren
x: Res
(informell gesprochen, mit Currying),PUT(x: Res)
undPATCH(x: Res)
sind univariate Funktionen des TypsRes → Res
.Eine Funktion
g: Res → Res
genannt wird global idempotent , wenng ○ g == g
, das heißt für alley: Res
,g(g(y)) = g(y)
.Lassen Sie
x: Res
eine Ressource undk = x.keys
. Eine Funktiong = f(x)
heißt left idempotent , wenny: Res
wir für jede habeng(g(y))|ₖ == g(y)|ₖ
. Dies bedeutet im Grunde, dass das Ergebnis dasselbe sein sollte, wenn wir uns die angewendeten Schlüssel ansehen.Ist
PATCH(x)
also nicht global idempotent, sondern bleibt idempotent. Und linke Idempotenz ist das, worauf es hier ankommt: Wenn wir ein paar Schlüssel der Ressource patchen, möchten wir, dass diese Schlüssel gleich sind, wenn wir sie erneut patchen, und wir kümmern uns nicht um den Rest der Ressource.Und wenn RFC davon spricht, dass PATCH nicht idempotent ist, spricht es von globaler Idempotenz. Nun, es ist gut, dass es nicht global idempotent ist, sonst wäre es eine kaputte Operation gewesen.
Nun versucht Jason Hoetgers Antwort zu demonstrieren, dass PATCH nicht einmal idempotent bleibt, aber es bricht zu viele Dinge, um dies zu tun:
t: Set<T> → Map<T, Boolean>
, definiert mitx in A iff t(A)(x) == True
. Bei Verwendung dieser Definition bleibt das Patchen idempotent.{id: 1, email: "[email protected]"}
muss mit übereinstimmen{email: "[email protected]"}
, sonst ist das Programm immer kaputt und der PATCH kann unmöglich Patch). Wenn die ID generiert wird, bevor sie mit dem Set verglichen wird, ist das Programm erneut fehlerhaft.Man kann Beispiele dafür machen, dass PUT nicht idempotent ist, wenn man die Hälfte der Dinge bricht, die in diesem Beispiel kaputt sind:
PUT /user/12 {email: "[email protected]"}
führt zu{email: "...", version: 1}
beim ersten und{email: "...", version: 2}
beim zweiten Mal.Alle obigen Beispiele sind natürliche Beispiele, denen man begegnen kann.
Mein letzter Punkt ist, dass PATCH nicht global idempotent sein sollte , da Sie sonst nicht den gewünschten Effekt erzielen. Sie möchten die E-Mail-Adresse Ihres Benutzers ändern, ohne den Rest der Informationen zu berühren, und Sie möchten die Änderungen einer anderen Partei, die auf dieselbe Ressource zugreift, nicht überschreiben.
quelle
Eine zusätzliche Information, die ich nur hinzufügen möchte, ist, dass eine PATCH-Anforderung im Vergleich zu einer PUT-Anforderung weniger Bandbreite verbraucht, da nur ein Teil der Daten nicht die gesamte Entität gesendet wird. Verwenden Sie einfach eine PATCH-Anforderung zum Aktualisieren bestimmter Datensätze wie (1-3 Datensätze), während Sie eine PUT-Anforderung zum Aktualisieren einer größeren Datenmenge verwenden. Das ist es, denken Sie nicht zu viel und machen Sie sich nicht zu viele Sorgen.
quelle