Write Requests

Introduction

This document shows how RESTHeart can use the PUT, POST, PATCH and DELETE verbs to create, modify and delete resources within a MongoDB database, using only the HTTP protocol.

With the exception of the root resource (/) which is read-only, all resources have a state represented in JSON format (see Representation Format for more information). Example

The following request:

PUT /db/coll {"description": "my first collection", "$currentDate": { "created_on": true }}

creates the collection coll in the database db setting its state as follows (the property _etag is automatically added by RESTHeart, see ETag for more information):

{
  "_id": "coll",
  "description": "my first collection",
  "created_on": { "$date": 1460708338344 },
  "_etag": { "$oid": "5710a3f12d174c97589e6127" }
}

This section focuses on the document resource. However the same concepts apply to any resource type, such as databases and collections.

Write verbs

The following table summarizes the semantic of the write verbs:

verb semantic
PUT

Upserts the resource identified by the request URL:

  • if the resource does not already exist, the PUT request creates it setting its state as specified in the request JSON body;
  • if the resource alreadyn exists, the PUT request sets the resource state as specified in the request JSON body.
  • $currentDate update operator is supported. Using any other update operator (such as `$min`) is not allowed and would result in BAD REQUEST response.
  • Properties keys can use the dot notation (such as `foo.bar`).
POST

Upserts a resource under the resource identified by the request URL:

  • if the resource does not already exist, the POST request creates it setting its state as specified in the request JSON body;
  • if the resource exists, the POST sets the resource properties as specified in the request JSON body.

The resource to upsert is identified by the _id property of the request JSON body. If the request body does not include it, the _id it is auto generated as a new ObjectId and the URL of the new document is returned in the response via the Location header.

  • $currentDate update operator is supported. Using any other update operator (such as `$min`) is not allowed and would result in BAD REQUEST response.
  • Properties keys can use the dot notation (such as `foo.bar`).
PATCH

While PUT and POST verbs replace the whole state of the resource identified by the request URL, PATCH verb only modifies the properties passed with the request JSON body. All write requests, including PATCH, have upsert semantic.

  • All update operators are allowed.
  • Properties keys can use the dot notation (such as `foo.bar`).
DELETE Deletes the resource identified by the request URL.

upsert

The term upsert means either to create a resource, if it does not already exist or to update it, if it does. It comes from joining the terms update and insert.

Dot notation

RESTHeart uses the dot notation to access the elements of an array and to access the fields of an embedded document.

The dot notation can be used in PUT, PATCH and POST verbs.

Array

To specify or access an element of an array by the zero-based index position, concatenate the array name with the dot (.) and zero-based index position, and enclose in quotes:

"<array>.<index>"

Example

{ "_id": "docid", "array": [ 1, 2, 3, 4, 5 ], ... } 
PATCH /db/coll/docid {"array.1": 100 }
{ "_id": "docid", "array": [ 1, 100, 3, 4, 5 ], ... } 

Embedded Documents

To specify or access a field of an embedded document with dot notation, concatenate the embedded document name with the dot (.) and the field name, and enclose in quotes:

"<embedded document>.<field>"

Example

{ "_id": "docid", "name": { "first": "Alan", "last": "Turing" }, ... } 
 
PATCH /db/coll/docid { "name.last": "Ford" }
 
{ "_id": "docid", "name": { "first": "Alan", "last": "Ford" }, ... } 

Update operators

RESTHeart allows to use all MongoDB update operators on PATCH requests. PUT and POST can only use $currentDate update operator.

Refer to MongoDB Update Operators documentation for more information.

Examples

Consider the following document

{
    "_id": "docid",
    "timestamp": { "$date": 1460708338344 },
    "array": [ {"id":1, "value": 2} ],
    "count": 10,
    "message": "hello world"
}

The following request will:

  • add the pi property (if no operator is specified the $set field operator is applied)
  • increment the properties count using the $inc field operator
  • add a new item to the array using the $push array operator
  • remove the property message using the $unset field operator
  • update the timestamp with the current date using the $currentDate operator
PATCH /db/coll/docid 
{
    "pi": 3.14,
    "$inc": { "count": 1 },
    "$push": { "array": { "id": 2, "value": 0 } },
    "$unset": {"message": null},
    "$currentDate": {"timestamp": true}
}

After the request completes, the resource state is updated to:

{
    "_id": "docid",
    "pi": 3.14,
    "timestamp": { "$date": 1460714673219 },
    "array": [ {"id":1, "value": 3}, {"id": 2, "value": 0 } ],
    "count": 11
}

Bulk Write Requests

Bulk write requests create, update or delete multiple documents with a single request.

POST an array of documents

In order to upsert multiple documents pass an array of documents as request body.

POST documents containing existing _ids to update them.

The bulk POST has the same behavior of PATCH: only the properties in the request data will be updated.

The response contains the URIs of the created documents.

All the upserted documents have the same _etag property value as reported in the ETag response header: to retrieve the upserted documents with a single request GET the collection filtering on the _etag property.

Example

request

POST /db/coll [ { "seq": 1 }, { "seq": 2 }, { "seq": 3 }, { "seq": 4 } ]

response

{
  "_embedded": [
      {
        "href": "/xxx/yyy/5716560a2d174cac010daf17"
      },
      {
        "href": "/xxx/yyy/5716560a2d174cac010daf18"
      },
      {
        "href": "/xxx/yyy/5716560a2d174cac010daf19"
      },
      {
        "href": "/xxx/yyy/5716560a2d174cac010daf1a"
      }
    ],
  "inserted": 4,
  "deleted": 0,
  "modified": 0,
  "matched": 0
} 

PATCH multiple documents using the wildcard document id

In order to modify the properties of multiple documents use the PATCH verb as follows:

PATCH bulk request

PATCH /db/coll/*?filter={<filter_query>}

The filter query parameter is mandatory and specifies a mongodb query.

The response contains the number of updated documents.

All the updated documents have the same _etag property value as reported in the ETag response header: to retrieve the updated documents with a single request GET the collection filtering on the _etag property.

Note the wildcard * document id in the URI: PATCH /db/coll/* is a bulk document update, where PATCH /db/coll modifies the properties of the collection.

Example - Add the property num to all documents missing it.

request

PATCH /db/coll/*?filter={"num": {"$exists": false } } { "num": 1 } 

response

{
  "inserted": 0,
  "deleted": 0,
  "modified": 9,
  "matched": 9
}

DELETE multiple documents using the wildcard document id

In order to delete multiple documents use the PATCH verb as follows:

PATCH bulk request

DELETE /db/coll/*?filter={<filter_query>}

The filter query parameter is mandatory and specifies a mongodb query.

The response contains the number of deleted documents.

Note the wildcard * document id in the URI:: DELETE /db/coll/* is a bulk document delete, where DELETE /db/coll deletes the collection (for safety, it requires the ETag request header to be specified).

Example - Delete all documents with whose creation_date is before 1/1/2016.

request

DELETE /db/coll/*?filter={"creation_date": {"$lt": {"$date": 1451606400000 } } }

response

{
  "inserted": 0,
  "deleted": 23,
  "modified": 0,
  "matched": 0
}