27

I want to implement the partial updates for my resource as i have large resource and want to update the partial information from it.I have gone through the following links but not
able to figure out whether to use HTTP POST or PATCH methods.

HTTP MODIFY verb for REST?

How to submit RESTful partial updates?

http://jacobian.org/writing/rest-worst-practices/

https://github.com/archiloque/rest-client/issues/79

https://datatracker.ietf.org/doc/html/draft-dusseault-http-patch-16

http://greenbytes.de/tech/webdav/draft-dusseault-http-patch-06.html

http://jasonsirota.com/rest-partial-updates-use-post-put-or-patch

http://bitworking.org/news/296/How-To-Do-RESTful-Partial-Updates

https://github.com/dharmafly/jsonpatch.js

Please suggest any valid solution for this.

Community
  • 1
  • 1
prashant
  • 2,181
  • 2
  • 22
  • 37

3 Answers3

95

According to RFC5789 (https://www.rfc-editor.org/rfc/rfc5789), this is precisely what PATCH is for:

Several applications extending the Hypertext Transfer Protocol (HTTP) require a feature to do partial resource modification. The existing HTTP PUT method only allows a complete replacement of a document. This proposal adds a new HTTP method, PATCH, to modify an existing HTTP resource.

The distinction between PATCH and PUT is described as:

The difference between the PUT and PATCH requests is reflected in the way the server processes the enclosed entity to modify the resource identified by the Request-URI. In a PUT request, the enclosed entity is considered to be a modified version of the resource stored on the origin server, and the client is requesting that the stored version be replaced. With PATCH, however, the enclosed entity contains a set of instructions describing how a resource currently residing on the origin server should be modified to produce a new version.

The limitations of POST are also described:

The PUT method is already defined to overwrite a resource with a complete new body, and cannot be reused to do partial changes. Otherwise, proxies and caches, and even clients and servers, may get confused as to the result of the operation. POST is already used but without broad interoperability (for one, there is no standard way to discover patch format support) [...]

I would suggest you read the RFC and make up your own mind, but to me this seems fairly clear-cut - PATCH requests should be processed as partial updates. (NB they are NOT idempotent, unlike PUT.)

EDIT: as pointed out by Eugene in the comments, although PATCH requests are "neither safe nor idempotent as defined by [RFC2616]", they can be made so:

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.

Community
  • 1
  • 1
Hugo Rodger-Brown
  • 11,054
  • 11
  • 52
  • 78
  • 20
    +1 I might add that `PATCH` can be made **idempotent** by including the `If-Match` header, as described in the RFC you are referring to. It is actually strongly suggested in the RFC to do that, as applying patches to the wrong version can screw up a reference, in contrast to a PUT that just replaces the whole thing. – Evgeniy Berezovsky Aug 06 '12 at 07:03
  • True - although in order to get this all working you would also need to be generating / using ETags correctly. – Hugo Rodger-Brown Aug 07 '12 at 08:25
  • Which is a good idea in many cases anyway, say for caching, but in particular for doing partial updates, where you most often want to make sure that you are patching a specific version of the resource. Sometimes enough context information can be embedded in the diff, but ETags are a diff-format independent way which is often easy to integrate into general-purpose frameworks that don't know anything about particular diff formats. – Evgeniy Berezovsky Apr 15 '13 at 01:55
  • Also note that PATCH RFC says: "_[in PATCH,] the enclosed entity contains a **set of instructions** describing how a resource [...] should be modified._". [Json-patch](http://tools.ietf.org/html/rfc6902) or [xml-patch](http://tools.ietf.org/html/rfc7351) are good candidates for media types to be used along with PATCH method. – botchniaque Sep 02 '14 at 13:20
-1

You should use method PATCH like described in RFC-7386 "json merge PATCH".

E.g. if you want to change value of "a" and removing "f" in resource like:

   {
     "a": "b",
     "c": {
       "d": "e",
       "f": "g"
     }
   }

You can achive this by sending:

       PATCH /target HTTP/1.1
       Host: example.org
       Content-Type: application/merge-patch+json

       {
         "a":"z",
         "c": {
           "f": null
         }
       }
-16

PATCH is to be used with a patch format, for document-level patching only (aka a diff on the actual representation). Its use for other purposes is dubious and debatable, and it's not clear that the method was designed for non-media-type uses.

In general a POST will be the right approach, but you may want to split your resource into multiple resources instead and modify those instead.

[Edited for clarity, as some don't read comments]

SerialSeb
  • 6,701
  • 24
  • 28
  • 6
    I don't see the how *prashanth* requirements: `partial updates for my resource` would conflict with what PATCH is supposed to do: `entity contains a set of instructions describing how a resource currently residing on the origin server should be modified to produce a new version.` This is from **rfc5789**, but the older **rfc2068** is similar. Also regarding the `diff on the actual bytes`, you aren't possibly getting this confused with HTTP ranges where implementors are only required to implement byte ranges (but this can be extended to other units)? – Evgeniy Berezovsky Aug 06 '12 at 07:00
  • 1
    I don't confuse http range requests with patch documents, no, thank you for pointing out the possible confusion to readers. The specification in question is quite clear about a patch document being a document that modifies the state of a resource, less clear on how to apply such document, leaving the choice up to you. From a spec perspective, it is encouraged to do conditionals, and strong etags are given in example, which we know are representation specific. Known or published diff formats (which you'd use in ReST) are document-specific, hence my answer. – SerialSeb Apr 14 '13 at 19:56
  • 3
    In general a POST request is used for creating resources, not updating them. – ChrisV Aug 08 '13 at 15:36
  • @chrisv Roy Fielding disagrees with you. http://roy.gbiv.com/untangled/2009/it-is-okay-to-use-post – Dick Chesterwood Nov 17 '14 at 20:11