SoftInstigate / restheart

Rapid API Development with MongoDB
https://restheart.org
GNU Affero General Public License v3.0
805 stars 171 forks source link

Use "POST" to update an existing document seems not work? #25

Closed chunlunglin closed 9 years ago

chunlunglin commented 9 years ago

Hi sir,

I would like to use "POST" to update an existing document, here is the original content of this document.

{ _embedded: { }, _links: { self: { href: "/testdb/testCollection/550be6fde4b045f91fa5d2c8" }, rh:coll: { href: "/testdb/testCollection" }, curies: [ { href: "http://www.restheart.org/docs/v0.10/#api-doc-{rel}", name: "rh" } ] }, _type: "DOCUMENT", _id: { $oid: "550be6fde4b045f91fa5d2c8" }, name: "iPhone5", color: "black", _etag: { $oid: "550be6fde4b045f91fa5d2c9" }, _lastupdated_on: "2015-03-20T09:23:09Z", _created_on: "2015-03-20T09:23:09Z" }

The command I use with "If-Match" header: curl -X POST -H "Content-Type: application/json" -H "If-Match: 550be6fde4b045f91fa5d2c9" -d "{'name':'iPhone6'}" http://{server ip}/testdb/testCollection

The server response as below HTTP/1.1 201 Created Auth-Token-Location: /_authtokens/user Location: http://{server ip}/testdb/testCollection/552de493e4b0f0155cbc3680 Access-Control-Expose-Headers: Location, ETag, Auth-Token, Auth-Token-Valid-Until, Auth-Token-Location Date: Wed, 15 Apr 2015 04:09:55 GMT ... ETag: 550be6fde4b045f91fa5d2c9 ... Access-Control-Allow-Credentials: true Content-Length: 0

It looks like a new document is created, and the original document did not been updated.

Is this normal?

Thank you.

mkjsix commented 9 years ago

Please try using a PATCH verb instead of POST (/cc @ujibang )

ujibang commented 9 years ago

in RESTHeart both PUT and POST have upsert semantic.

In order to update an existing document using POST, you need to put the _id property in the document.

so the correct request is:

curl -X POST -H "Content-Type: application/json" -H "If-Match: 550be6fde4b045f91fa5d2c9" -d "{'_id': {
'$oid': "550be6fde4b045f91fa5d2c8'}, 'name':'iPhone6'}" http://{server ip}/testdb/testCollection

note that this will replace the whole document that will result having 2 properties: _id and name.

If you want just to update the passed properties you need to use PATCH as mkjsix pointed out.

curl -X PATCH -H "Content-Type: application/json" -H "If-Match: 550be6fde4b045f91fa5d2c9" -d "{ 'name':'iPhone6'}" http://{server ip}/testdb/testCollection/550be6fde4b045f91fa5d2c8
chunlunglin commented 9 years ago

Really thanks for the answer. It works well.