2010-03-02 2 views
15

Warum muss eine HTTP-PUT-Anforderung eine Repräsentation eines "ganzen" Zustands enthalten und kann nicht nur eine partielle sein?Was ist die Rechtfertigung für die Ablehnung teilweisen PUT?

Ich verstehe, dass dies die bestehende Definition von PUT ist - diese Frage ist über den Grund (die Gründe), warum es so definiert werden würde.

heißt:

Was durch die Verhinderung Teil PUTs gewonnen wird?

Warum wurde das Verhindern idempotenter partieller Aktualisierungen als akzeptabler Verlust betrachtet?

+1

Sehen Sie hier für eine weitere Diskussion der gleichen Frage: http://tech.groups.yahoo.com/group/rest-discuss/message/17415 - Ich habe alles gelesen und sehe keinen zwingenden Grund für die Definition von PUT nur für vollständige Updates. – lkraider

+0

@lkraider Ich stimme zu. Ich sehe keinen Vorteil außer einigen, weil die HTTP-Spezifikation eine Unterscheidung zwischen PUT und PATCH macht (was nicht sehr praktisch ist). – Brenden

Antwort

15

PUT bedeutet, was in der HTTP-Spezifikation definiert ist. Clients und Server können diese Bedeutung nicht ändern. Wenn Clients oder Server PUT in einer Weise verwenden, die ihrer Definition widerspricht, kann mindestens Folgendes passieren:

Put ist per Definition idempotent. Das bedeutet, dass ein Client (oder Vermittler!) Einen PUT beliebig oft wiederholen kann und sicher sein muss, dass der Effekt der gleiche ist. Angenommen, ein Intermediär empfängt eine PUT-Anforderung von einem Client. Wenn die Anforderung an den Server weitergeleitet wird, liegt ein Netzwerkproblem vor. Der Intermediär weiß definitionsgemäß, dass er den PUT erneut versuchen kann, bis er erfolgreich ist. Wenn der Server PUT nicht idempotent verwendet, haben diese möglichen Mehrfachaufrufe einen unerwünschten Effekt.

Wenn Sie eine partielle Aktualisierung durchführen möchten, verwenden Sie PATCH oder verwenden Sie POST für eine Unterressource und geben Sie 303 Weitere Informationen zu der Hauptressource, z.


POST /account/445/owner/address 
Content-Type: application/x-www-form-urlencoded 

street=MyWay&zip=22222&city=Manchaster 


303 See Other 
Location: /account/445 

EDIT: Auf die allgemeine Frage, warum teilweise Updates können nicht idempotent werden:

Eine partielle Update kann nicht im Allgemeinen idempotent werden, da die Idempotenz auf die Semantik Medientyp abhängt. IOW, können Sie möglicherweise ein Format angeben, das idempotente Patches zulässt, aber PATCH kann nicht garantiert werden, dass es für jeden Fall idempotent ist. Da die Semantik einer Methode (aus Gründen der Orthogonalität) keine Funktion des Medientyps sein kann, muss PATCH als nicht idempotent definiert werden. Und PUT (als idempotent definiert) kann nicht für Teilupdates verwendet werden.

+3

Hallo Jan, wie ich schon sagte; "Ich verstehe, dass dies die existierende Definition von PUT ist - diese Frage betrifft die Gründe, warum sie so definiert werden". Ihr Beispiel im zweiten Absatz impliziert, dass das partielle Update nicht-idempotent ist - offensichtlich ist das was PATCH ist. Ich interessiere mich für * idempotent * partielle Updates - d. H. Eine partielle PUT. – Mike

+0

PATCH wird neu hinzugefügt. Ebenfalls; Jan - Idempotenz muss nicht auf eine bestimmte Menge von Medientypen hinsichtlich ihrer Definition im Protokoll angewiesen sein, die Semantik einer Methode ist eine Funktion ihrer Definition als Teil einer einheitlichen Schnittstelle. Ich kämpfe immer noch darum herauszufinden, was tatsächlich verloren geht, indem man die Definition von PUT auf etwas so Einfaches wie "eine idempotente Zustandsänderung" (dh eine, die Partials nicht verhindert) umstellt. – Mike

+0

@Mike, wie ich oben erklären wollte: Sie können ein Teilupdate nicht als idempotent definieren, ohne den jeweiligen Medientyp zu berücksichtigen. Die Idempotenz hängt vom verwendeten Medientyp ab, und da Sie die Semantik der Methoden nicht von der Semantik des Medientyps abhängig machen können, kann ein Update nur für den allgemeinen Fall idempotent sein, wenn es sich um einen vollständigen Ersatz handelt. Eine Methode, die eine partielle Aktualisierung angibt, MUSS nicht-idempotent definiert werden. IOW, Sie können einfach niemals eine "'eine idempotente Zustandsänderung' (d. H. Eine, die Partials nicht verhindert)" definieren. Es ist ein Widerspruch in sich. –

-1

Weil, ich denke, dies würde in inkonsistenten "Ansichten" übersetzt haben, wenn mehrere gleichzeitige Clients auf den Zustand zugreifen. Es gibt keine "partielle Dokument" -Semantik in REST, soweit ich das beurteilen kann, und wahrscheinlich waren die Vorteile des Hinzufügens angesichts der Komplexität des Umgangs mit dieser Semantik im Kontext der Nebenläufigkeit den Aufwand nicht wert.

Wenn das Dokument groß ist, gibt es nichts, was Sie daran hindert, mehrere unabhängige Dokumente zu erstellen und ein übergreifendes Dokument zu erstellen, das sie miteinander verbindet. Sobald alle Teile gesammelt sind, kann ein neues Dokument auf dem Server gesammelt werden.

Also, wenn man bedenkt "Workaround" kann diese "Einschränkungen", kann ich verstehen, warum diese Funktion nicht den Schnitt gemacht.

+1

Entschuldigung - Ich verstehe den Punkt über inkonsistente Ansichten nicht, die durch teilweise idempotente Aktualisierungen erzeugt werden, die sich im Verhalten von "vollen" idempotenten Aktualisierungen unterscheiden. Ich bin auch hinsichtlich der vorgeschlagenen Zunahme der Komplexität unsicher, aus Sicht der Protokolldefinition. – Mike

-1

Kurze Antwort: SÄURE der PUT-Operation und des Status der aktualisierten Entität.

Lange Antwort:

RFC 2616: Absatz 2.5, "POST-Methode fordert den geschlossenen Einheit als eine neue untergeordnete der angeforderten URL akzeptiert zu werden". Abschnitt 2.6, "PUT-Methode fordert die eingeschlossene Entität an, an der angegebenen URL gespeichert zu werden".

Da bei jeder Ausführung von POST die Semantik eine neue Entitätsinstanz auf dem Server erstellt, bildet POST eine ACID-Operation. Wenn Sie denselben POST zweimal mit derselben Entität im Body wiederholen, kann dies jedoch zu einem anderen Ergebnis führen, wenn zum Beispiel auf dem Server kein Speicher mehr für die Speicherung der neuen Instanz vorhanden ist, die erstellt werden muss. Daher ist POST nicht idempotent.

PUT auf der anderen Seite hat eine Semantik der Aktualisierung einer bestehenden Entität. Es gibt keine Garantie dafür, dass auch wenn ein teilweises Update idempotent ist, es auch ACID ist und zu einem konsistenten und gültigen Entitätsstatus führt. Um die ACIDität sicherzustellen, erfordert die PUT-Semantik, dass die vollständige Entität gesendet wird. Selbst wenn dies kein Ziel für die HTTP-Protokollautoren wäre, würde die Idempotenz der PUT-Anforderung als Nebeneffekt des Versuches auftreten, ACID durchzusetzen.

Wenn der HTTP-Server natürlich die Semantik der Entitäten genau kennt, kann er partielle PUTs zulassen, da er durch serverseitige Logik die Konsistenz der Entität sicherstellen kann. Dies erfordert jedoch eine enge Kopplung zwischen den Daten und dem Server.

+0

"Es gibt keine Garantie, dass, selbst wenn ein teilweises Update idempotent ist, es auch atomar ist" - Hmm, das verstehe ich nicht. Wie könnte ein idempotentes Update nicht atomar sein? – Mike

+0

Ich deutete ACIDness an, als ich Atomizität sagte. Mit anderen Worten, ich betrachte eine Operation als "atomar", wenn sich die Entität am Ende derselben in einem gültigen und konsistenten Zustand befindet. Sollte ACID explizit anstelle von Atom verwendet haben. –

-1

Mit einer vollständigen Dokumentaktualisierung ist es offensichtlich, ohne dass Sie Details über die jeweilige API oder ihre Einschränkungen bezüglich der Dokumentstruktur wissen, was das resultierende Dokument nach der Aktualisierung sein wird.

Wenn eine bestimmte Methode bekanntlich nie eine teilweise Inhaltsaktualisierung war und eine von jemandem bereitgestellte API nur diese Methode unterstützte, dann wäre immer klar, was jemand mit der API tun müsste, um ein Dokument zu ändern gegebener Satz gültiger Inhalte.

Verwandte Themen