标签云

微信群

扫码加入我们

WeChat QR Code

First of all, some definitions:PUT is defined in Section 9.6 RFC 2616:The PUT method requests that the enclosed entity be stored under the supplied Request-URI. If the Request-URI refers to an already existing resource, the enclosed entity SHOULD be considered as a modified version of the one residing on the origin server. If the Request-URI does not point to an existing resource, and that URI is capable of being defined as a new resource by the requesting user agent, the origin server can create the resource with that URI.PATCH is defined in RFC 5789:The PATCH method requests that a set of changes described in the request entity be applied to the resource identified by the Request- URI.Also according to RFC 2616 Section 9.1.2 PUT is Idempotent while PATCH is not.Now lets take a look at a real example. When I do POST to /users with the data {username: 'skwee357', email: '[email protected]'} and the server is capable of creating a resource, it will respond with 201 and resource location (lets assume /users/1) and any next call to GET /users/1 will return {id: 1, username: 'skwee357', email: '[email protected]'}.Now lets say I want to modify my email. Email modification is considered "a set of changes" and therefor I should PATCH /users/1 with "patch document". In my case it would be a json {email: '[email protected]'}. The server then returns 200 (assuming permission are ok). This brings me to first question:PATCH is NOT idempotent. It said so in RFC 2616 and RFC 5789. However if I'll issue the same PATCH request (with my new email) Ill get the same resource state (with my email being modified to the requested value). Why isn't PATCH then idempotent?PATCH is a relatively new verb (RFC introduced in March 2010), and it comes to solve the problem of "patching" or modifying a set of fields. Before PATCH was introduced, everybody used PUT to update resource. But after PATCH was introduced, it leaves me confused what is PUT used for then? And this brings me to second (and the main) question:Whats the real difference between PUT and PATCH? I've read somewhere the PUT might be used to replace entire entity under specific resource, so one should send the full entity (instead of set of attributes as with PATCH). What is the real practical usage for such case? When would you like to replace / overwrite an entity under specific resource URI and why such operation is not considered as updating / patching the entity? The only practical use case I see for PUT is issuing a PUT on collection, i.e. /users to replace the entire collection. Issuing PUT on a specific entity makes no sense after PATCH was introduced. Am I wrong?


a) it's RFC 2616, not 2612. b) RFC 2616 has been obsoleted, the current spec of PUT is in greenbytes.de/tech/webdav/rfc7231.html#PUT, c) I don't get your question; isn't it pretty obvious that PUT can be used to replace any resource, not only a collection, d) before PATCH was introduced, people usually used POST, e) finally, yes, a specific PATCH request (depending on the patch format) can be idempotent; it's just that it's not generally.

2019年08月26日42分03秒

if it helps I've wrote an article on the PATCH vs PUT eq8.eu/blogs/36-patch-vs-put-and-the-patch-json-syntax-war

2019年08月26日42分03秒

Simple: POST creates an item in a collection. PUT replaces an item. PATCH modifies an item. When POSTing, the URL for the new item is computed and returned in the response, whereas PUT and PATCH require a URL in the request. Right?

2019年08月26日42分03秒

This sentence isn't quite correct: "But it is idempotent: whenever A goes in, B always comes out". For example, if you were to GET /users/1 before the Post Office updated the zip code and then again make the same GET /users/1 request after the Post Office's update, you would get two different responses (different zip codes). The same "A" (GET request) is going in, but you're getting different results. Yet GET is still idempotent.

2019年08月27日42分03秒

JasonHoetger GET is safe (presumed to cause no change), but is not always idempotent. There is a difference. See RFC 2616 sec. 9.1.

2019年08月26日42分03秒

DanLowe: GET most definitely is guaranteed to be idempotent. It says exactly that in Section 9.1.2 of RFC 2616, and in the updated spec, RFC 7231 section 4.2.2, that "Of the request methods defined by this specification, PUT, DELETE, and safe request methods are idempotent." Idempotence just doesn't mean "you get the same response every time you make the same request". 7231 4.2.2 goes on to say: "Repeating the request will have the same intended effect, even if the original request succeeded, though the response might differ."

2019年08月26日42分03秒

JasonHoetger I'll concede that, but I don't see what it has to do with this answer, which discussed PUT and PATCH and never even mentions GET...

2019年08月26日42分03秒

Ah, the comment from JasonHoetger cleared it up: only the resulting states, rather than responses, of multiple idempotent method requests need be identical.

2019年08月26日42分03秒

Assuming that the server also allows issuing PUT at /users, this would make PUT non-idempotent as well. All this comes down to is how the server is designed to handle requests.

2019年08月27日42分03秒

So, We could build an API only with PATCH operations. Then, what becomes the REST principle of using http VERBS to make CRUD actions on Resources ? Aren't we overcomplexifying the PATCH borders gentlemen here ?

2019年08月26日42分03秒

If PUT is implemented on a collection (e.g. /users), any PUT request should replace the contents of that collection. So a PUT to /users should expect a collection of users and delete all others. This is idempotent. It isn't likely you'd do such a thing on a /users endpoint. But something like /users/1/emails may be a collection and it may be perfectly valid to allow replacing the entire collection with a new one.

2019年08月26日42分03秒

Though this answer provides a great example of idempotence, I believe this may muddy the waters in typical REST scenarios. In this case you have a PATCH request with an additional op action that is triggering specific server side logic. This would require server and client to be aware of the specific values to pass for the op field to trigger server side workflows. In more straightforward REST scenarios, this type of op functionality is bad practice and should likely be handled directly through HTTP verbs.

2019年08月27日42分03秒

I would never consider issuing a PATCH, only POST and DELETE, against a collection. Is this really ever done? Can PATCH therefore be considered idempotent for all practical purposes?

2019年08月26日42分03秒

It may be worth adding: in William Durand's article (and rfc 6902) there are examples where "op" is "add". This is obviously not idempotent.

2019年08月26日42分03秒

Or you can make easier and use the RFC 7396 Merge Patch instead and avoid building patch JSON.

2019年08月27日42分03秒

for nosql tables, differences between patch and put is important, because nosql have no columns

2019年08月26日42分03秒