5 ms·
PATCH Method for HTTP
- scott_w 14y agoIt's a shame that Patch isn't idempotent. My preference for updating data across the web is to send only the information that is different, and the service ensures everything else remains the same. Put doesn't quite cut it in this case (technically, it's supposed to completely replace a resource). Are there any advantages for declaring Patch to be not idempotent? I'm assuming it allows appending to a single resource?
- ibotty 14y agoyes. to quote the rfc: There are also cases where patch formats do not need to operate from a known base-point (e.g., appending text lines to log files, or non- colliding rows to database tables) [...]
- scott_w 14y agoYes, I saw that. Personally, I think Post does a good enough job for that. I know it's technically supposed to create a sub-resource, but it seems to work for appending to the same resource just as well. I'm a little uncertain of the case for using Patch to append rows to a database. Surely that's a case where Post does a better job?
- rfugger 14y agoPOST would make more sense if each row is its own resource. PATCH would make more sense if the entire table is its own resource, without addressable sub-resources (rows).
- scott_w 14y agoAs far as the spec is concerned, yes I agree. On a more personal level, I'm of the opinion that Post can append to an existing resource, without adding a new resource. Allowing for this practicality in the spec would allow Patch to be only idempotent.
- ibotty 14y agothat would be nice, indeed, but seems impossible now.
- quesera 14y agoHTTP PATCH can only be idempotent if the underlying patch mechanism is idempotent, right? At the protocol level, there are no guarantees. At the application level, you can fake it (in the non-mathematical sense) by checking sentinels/guids or testing for applicability. This provides safety, but requires code. But that's not really idempotence. I don't see any way that the IETF could specify a generic idempotent patch mechanism, or declare an arbitrary mechanism to be idempotent. EDIT: it looks like you want idempotence a la SQL UPDATE. That seems eminently doable in the application layer. Specifying it in an RFC would be inadequately generic for a whole new HTTP verb, I think.
- rmccue 14y agoBy definition, GET, HEAD, PUT and DELETE are idempotent: http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html I personally agree with the parent. PATCH should be idempotent; overwriting values with new values is idempotent and that should be written into the spec rather than avoiding it in favour of things like writing logs (which IMHO should be a POST).
- quesera 14y agoYes, but GET, HEAD, PUT, and DELETE do very different things. You can write an idempotent PATCH mechanism. If that's what you want, you can do it. You control the server, so you can restrict the accepted patch formats to idempotent ones. Adding an HTTP verb doesn't make patching magically happen. Someone has to write the logic, either you or your framework authors. Obviously there will be different mechanisms and some will be effectively idempotent. Again, not in the mathematical or functional programming sense, but in the colloquial DBA sense, at least. Limiting HTTP PATCH at the protocol level would be a huge mistake, I think. None of this should be construed to mean that I see a clear need for a new HTTP verb, though.
- Xylakant 14y agoNote of care: SQL Updates are not idempotent. "UPDATE table SET a = a + 1".
- m_eiman 14y agoWouldn't combining it with an If-Match header make it idempotent, assuming the server actually performs the check before applying the patch?
- _mhp_ 14y agoSection 2 contains: A PATCH request can be issued in such a way as to be idempotent, which also helps prevent bad outcomes [...] Clients using this kind of patch application SHOULD use a conditional request [...] For example, the client can use a strong ETag [RFC2616] in an If-Match header on the PATCH request. So you can, but aren't obliged to.
- zedr 14y agoConcurrent clients PUTting and PATCHing of a single resource. Successive (not sequential) PATCHes are not guaranteed to produce the same outcome.
- bruth 14y agoConditional requests are the way to go to be more transparent to clients, but the server implementation can _test_ values prior to patching the resource. For example, the JSON Patch spec has a "test" operation: http://tools.ietf.org/html/draft-ietf-appsawg-json-patch-02#section-4.6 http://tools.ietf.org/html/draft-ietf-appsawg-json-patch-02#... so you could accept the same patch, but simply test if the resource is up-to-date before patching it.
- zacharyvoase 14y agoCoincidentally, I recently read this article, entitled “You Cannot Correctly Represent Change Without Immutability”: http://tapestryjava.blogspot.se/2012/07/you-cannot-correctly-represent-change.html http://tapestryjava.blogspot.se/2012/07/you-cannot-correctly... The point is, the ‘patch’ itself is a transformation defined by a 2-tuple of the old value and the delta (whereas a ‘put’ would be defined as the 2-tuple of the old value and the new value). Because the old value is referenced by the request URI (which is mutable), simply specifying the delta itself is not idempotent. Of course, following the RFC's advice and adding the ETag means you're specifying both the delta and the old value, which makes the operation idempotent.
- tamasnet 14y agoWhile this is certainly makes the request's intent more clear, I suspect there isn't much gained here over simply POSTing the patch content. Other request methods can be implemented by the HTTP server itself in terms of the filesystem (e.g. PUT "simply" writes the content stream to a local file), but PATCH would require the server itself to have specific knowledge of the patch format and how to apply it in order to be useful. This could be farmed out a plugin or external program, but such a thing could just as easily live as a POST processor in [insert favourite language here] without needing to make any changes to the HTTP server or standards.
- Arnout 14y agoNow annoyingly the ELB on AWS just bounces PATCH requests with a 405 Method Not Allowed. Our services are affected by this and I noticed there is a bug open over at Heroku regarding the same issue. It's something Amazon don't document though so you only find out through testing after you already created your planned stack...
- rmccue 14y agoIndeed, it also affects http://httpbin.org/ http://httpbin.org/ which makes it way harder to test clients. Considering the spec has been out since 2010, you'd think they'd have fixed it by now.
- sjtgraham 14y agoIt's a Request For Comments and not a standard. It's also at the most immature level on the standards track. Why would they implement something that may change drastically or never be implemented widely enough to justify the engineering effort?
- einhverfr 14y agoI can't wait to submit HTML forms with a PATCH method ;-)
- ibotty 14y agothat made a good laugh! :D. thanks/
- kbanman 14y agoCould you elaborate on your sarcasm? Given due care on server side, I'm not sure why that would be so terrible.
- einhverfr 14y agoBecause normally with a form you are submitting a full, complete resource from the web server's perspective.
- almost 14y agoI gave a short presentation (5 minutes) about the PATCH verb and RESTful APIs at local user group last year. Possibly someone will find the slide useful (or just enjoy the kitten pictures ;p): http://almostobsolete.net/talks/http_rest_patch_kittens/ http://almostobsolete.net/talks/http_rest_patch_kittens/
- sjtgraham 14y agoCan somewhere point me to the part of RFC 2616 that says "The PUT method is already defined to overwrite a resource with a complete new body, and cannot be reused to do partial changes."
- fzzzy 14y agoThis was the first thing that came to mind to me: can't PUT take a Range header, and would that not be the same as patch?
- munkydung 14y agoPATCH will be supported in Rails http://weblog.rubyonrails.org/2012/2/25/edge-rails-patch-is-the-new-primary-http-method-for-updates/ http://weblog.rubyonrails.org/2012/2/25/edge-rails-patch-is-...