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?
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) [...]
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?
POST 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).
HTTP 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.
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).
Yes, 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.
I love that for rearranging items in lists with user-defined orders. It lets you update the entire set with two commands - one to give the moved item its new position, and one to increase the position of every item after it.
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.
Conditional 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#... so you could accept the same patch, but simply test if the resource is up-to-date before patching it.
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.
While 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.
Now 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...
Indeed, it also affects 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.
It'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?
I 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):
Can 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."
28 comments
[ 2.9 ms ] story [ 76.2 ms ] threadMy 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?
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?
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.
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.
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).
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.
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.
Given due care on server side, I'm not sure why that would be so terrible.
http://almostobsolete.net/talks/http_rest_patch_kittens/