{"id":118,"date":"2010-09-02T20:29:27","date_gmt":"2010-09-03T03:29:27","guid":{"rendered":"http:\/\/www.corneliadavis.com\/blog\/?p=118"},"modified":"2010-09-02T20:29:27","modified_gmt":"2010-09-03T03:29:27","slug":"why-put-cant-be-used-for-partial-updates","status":"publish","type":"post","link":"https:\/\/corneliadavis.com\/blog\/2010\/09\/02\/why-put-cant-be-used-for-partial-updates\/","title":{"rendered":"Why PUT can&#8217;t be used for partial updates"},"content":{"rendered":"<p>I&#8217;ve been discussing PUT vs. PATCH with some colleagues and finally took the time to come up with a concrete example of why PUT absolutely should not be used for partial updates of resources.  One colleague pointed out the following points made by Roy Fielding on the <a href=\"http:\/\/www.imc.org\/atom-protocol\/mail-archive\/msg05425.html\">AtomPub listserv<\/a>:<\/p>\n<blockquote><p>FWIW, PUT does not mean store.  I must have repeated that a million times in webdav and related lists.  HTTP defines the intended semantics of the communication &#8212; the expectations of each party. The protocol does not define how either side fulfills those expectations, and it makes damn sure it doesn&#8217;t prevent a server from having absolute authority over its own resources.  Also, resources are known to change over time, so if a server accepts an invalid Atom entry via PUT one second and then immediately thereafter decides to change it to a valid entry for later GETs, life is grand.<\/p><\/blockquote>\n<p>Roy&#8217;s right, of course, but there is a subtlety that is easily overlooked.  Sure, the server has the authority to &#8220;fix&#8221; the resource representation, for example, it might modify part of the resource representation passed in (i.e. if the client tries to modify the server controlled <em>id<\/em> property, the server can ignore that), but there is an important constraint that the server has to follow.  PUT needs to be idempotent!  This means the server can&#8217;t use the current state of the resource to &#8220;fix&#8221; the resource representation passed in.  Have a look at the following simple example:<\/p>\n<p>Let&#8217;s say that I have a resource that consists of a couple of properties, A and B, and I want to use PUT to support partial updates of this resource.  The payload of the PUT will carry the properties that we wish to update; if a resource property is not present in the payload then that property will remain unchanged in the resource.  We&#8217;re playing the &#8220;the server has control over what they do with the resource property&#8221; card.  Check out the following sequence of operations then:<a href=\"https:\/\/i0.wp.com\/www.corneliadavis.com\/blog\/wp-content\/uploads\/2010\/09\/PUTIdempotent.jpg\"><img data-recalc-dims=\"1\" decoding=\"async\" loading=\"lazy\" class=\"alignnone wp-image-119\" title=\"PUTIdempotent\" src=\"https:\/\/i0.wp.com\/www.corneliadavis.com\/blog-old\/wp-content\/uploads\/2010\/09\/PUTIdempotent.jpg?resize=500%2C375\" alt=\"\" width=\"500\" height=\"375\" \/><\/a><\/p>\n<p><a href=\"http:\/\/www.corneliadavis.com\/blog\/wp-content\/uploads\/2010\/09\/PUTIdempotent.jpg\"><\/a>Ouch!  The PUT is not idempotent!  Client 1 does the same PUT twice, leaving the resource in two different states &#8211; one of which could very well be inconsistent.  PUT semantics, when correctly followed, give the client the ability to control the consistency of the resource they are writing.<\/p>\n<p>Hence <a href=\"http:\/\/tools.ietf.org\/pdf\/rfc5789.pdf\">RFC 5789 &#8211; PATCH Method for HTTP<\/a>.  PATCH does not have the constraint of being idempotent so the client cannot simply retry requests for which they never received a response.  I do think it is interesting that RFC 5789 includes the following:<\/p>\n<blockquote><p>A PATCH request can be issued in such a way as to be idempotent, which also helps prevent bad outcomes from collisions between two PATCH requests on the same resource in a similar time frame. Collisions from multiple PATCH requests may be more dangerous than PUT collisions because some patch formats need to operate from a known base-point or else they will corrupt the resource. Clients using this kind of patch application SHOULD use a conditional request such that the request will fail if the resource has been updated since the client last accessed the resource. For example, the client can use a strong ETag [RFC2616] in an If-Match header on the PATCH request.<\/p><\/blockquote>\n<p>That is, you could make PATCH idempotent if you use the likes of ETags and conditional invocations.  The same could be said for a PUT that does partial updates but the opportune world here is &#8220;could&#8221; &#8211; PUT is required to be idempotent even without the use of things such as ETags.<\/p>\n<p>All of that said, while neither RFC 2616, nor RFC 5789 require the use of ETag like mechanisms, in most cases it&#8217;s a good idea.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>I&#8217;ve been discussing PUT vs. PATCH with some colleagues and finally took the time to come up with a concrete example of why PUT absolutely should not be used for partial updates of resources. One colleague pointed out the following points made by Roy Fielding on the AtomPub listserv: FWIW, PUT does not mean store. [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"nf_dc_page":"","_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[33],"tags":[69,77,78,80],"class_list":["post-118","post","type-post","status-publish","format-standard","hentry","category-standards","tag-idempotent","tag-patch","tag-put","tag-rest"],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/corneliadavis.com\/blog\/wp-json\/wp\/v2\/posts\/118","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/corneliadavis.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/corneliadavis.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/corneliadavis.com\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/corneliadavis.com\/blog\/wp-json\/wp\/v2\/comments?post=118"}],"version-history":[{"count":0,"href":"https:\/\/corneliadavis.com\/blog\/wp-json\/wp\/v2\/posts\/118\/revisions"}],"wp:attachment":[{"href":"https:\/\/corneliadavis.com\/blog\/wp-json\/wp\/v2\/media?parent=118"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/corneliadavis.com\/blog\/wp-json\/wp\/v2\/categories?post=118"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/corneliadavis.com\/blog\/wp-json\/wp\/v2\/tags?post=118"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}