it-swarm.com.de

Warum ist die PATCH-Methode nicht idempotent?

Ich habe mich darüber gewundert.

Angenommen, ich habe eine user Ressource mit den Feldern id und name. Wenn ich ein Feld aktualisieren möchte, kann ich einfach eine PATCH-Anfrage an die Ressource wie diese senden

PATCH /users/42
{"name": "john doe"} 

Und dann aktualisiert die Anwendung den Namen des Benutzers 42.

Aber warum wäre das Ergebnis anders, wenn ich diese Anfrage wiederhole?

Nach RFC 5789

PATCH ist weder sicher noch idempotent

54
mattecapu

Eine PATCH-Anfrage kann idempotent sein, muss es aber nicht sein. Das ist der Grund, warum es als nicht idempotent charakterisiert wird.

Ob PATCH idempotent sein kann oder nicht, hängt stark davon ab, wie die erforderlichen Änderungen kommuniziert werden.
Wenn das Patch-Format beispielsweise die Form {change: 'Name' from: 'benjamin franklin' to: 'john doe'} Hat, hat jede PATCH-Anforderung nach der ersten einen anderen Effekt (eine Fehlerantwort) als die erste Anforderung.
Ein weiterer Grund für die Nicht-Idempotenz kann sein, dass das Anwenden der Änderung auf etwas anderes als die ursprüngliche Ressource die Ressource ungültig machen kann. Dies wäre dann auch der Fall, wenn Sie die Änderung mehrmals anwenden.

Ich denke klare Antwort, wenn PATCH in nicht idempotent ist dieser Absatz aus RFC 5789:

Es gibt auch Fälle, in denen Patch-Formate nicht von einem bekannten Basispunkt aus ausgeführt werden müssen (z. B. Anhängen von Textzeilen an Protokolldateien oder nicht kollidierende Zeilen an Datenbanktabellen). In diesem Fall ist die gleiche Sorgfalt bei Clientanforderungen nicht erforderlich .

Da RFC angibt, dass der Patch einige "allgemeine Änderungen" an der Ressource enthält, sollten wir über das typische Ersetzen von Feldern hinausgehen. Wenn die Ressource für einen Zähler bestimmt ist, kann der Patch dessen Inkrement anfordern, was eindeutig kein Idempot ist.

12
Ivan

PATCH -Anforderungen beschreiben eine Reihe von Operationen, die auf eine Ressource angewendet werden sollen. Wenn Sie dieselbe Menge von Operationen zweimal auf dieselbe Ressource anwenden, ist das Ergebnis möglicherweise nicht dasselbe. Dies liegt daran, dass die Definition der Vorgänge bei Ihnen liegt. Mit anderen Worten, Sie müssen die Zusammenführungsregeln definieren.

Denken Sie daran, dass eine PATCH -Anforderung zum Patchen von Ressourcen in vielen verschiedenen Formaten verwendet werden kann, nicht nur in JSON.

Eine PATCH -Anforderung kann also idempotent sein , wenn Sie die Zusammenführungsregeln als idempotent definieren .

Idempotentes Beispiel:

// Original resource
{
  name: 'Tito',
  age: 32
}

// PATCH request
{
  age: 33
}

// New resource
{
  name: 'Tito',
  age: 33
}

Nicht idempotentes Beispiel:

// Original resource
{
  name: 'Tito',
  age: 32
}

// PATCH request
{
  $increment: 'age'
}

// New resource
{
  name: 'Tito',
  age: 33
}

Im zweiten Beispiel habe ich eine "Mongo-ähnliche" Syntax verwendet, die ich zum Inkrementieren eines Attributs erfunden habe. Dies ist eindeutig nicht idempotent, da das mehrfache Senden derselben Anfrage jedes Mal zu unterschiedlichen Ergebnissen führen würde.

Jetzt fragen Sie sich vielleicht, ob die Verwendung einer solchen erfundenen Syntax gültig ist. Nach Standards ist es:

Der Unterschied zwischen den PUT- und PATCH-Anforderungen spiegelt sich in der Art und Weise wider, wie der Server die eingeschlossene Entität verarbeitet, um die durch den Anforderungs-URI identifizierte Ressource zu ändern. In einer PUT-Anforderung wird die eingeschlossene Entität als geänderte Version der auf dem Origin-Server gespeicherten Ressource betrachtet, und der Client fordert an, dass die gespeicherte Version ersetzt wird. Bei PATCH enthält die beigefügte Entität jedoch eine Reihe von Anweisungen, die beschreiben, wie eine Ressource, die sich derzeit auf dem Origin-Server befindet, geändert werden sollte, um eine neue Version zu erstellen.

Und Sie fragen sich vielleicht auch, ob es erholsam ist, PATCH Anfragen auf diese Weise zu verwenden, und viele Leute denken, dass dies nicht der Fall ist gute Antwort mit vielen Kommentaren zu diesem Thema.

4
Jbm