Edit Page

Write Documents

Introduction

You will learn how to insert, update and delete documents in a collection.

Before running the example requests

The following step by step tutorial assumes that RESTHeart is running on localhost with the default configuration: the database restheart is bound to / and the user admin exists with default password secret.

Tip
To run RESTHeart refer to Setup section.

To create the restheart db, run the following:

PUT / HTTP/1.1

The examples on this page use the inventory collection. To create the inventory collection, run the following:

PUT /inventory HTTP/1.1

To populate the inventory collection, run the following:

POST /inventory HTTP/1.1

[
   { "item": "journal", "qty": 25, "size": { "h": 14, "w": 21, "uom": "cm" }, "status": "A" },
   { "item": "notebook", "qty": 50, "size": { "h": 8.5, "w": 11, "uom": "in" }, "status": "A" },
   { "item": "paper", "qty": 100, "size": { "h": 8.5, "w": 11, "uom": "in" }, "status": "D" },
   { "item": "planner", "qty": 75, "size": { "h": 22.85, "w": 30, "uom": "cm" }, "status": "D" },
   { "item": "postcard", "qty": 45, "size": { "h": 10, "w": 15.25, "uom": "cm" }, "status": "A" }
]

Content-Type

For write requests use Content-Type: application/json

In this case the request body is just the JSON representation of the MongoDB BSON format, see Representation format for more information.

See the following example:

POST /coll HTTP/1.1
Content-Type: application/json

{
    "b": true,
    "n": 1,
    "ns": "1",
    "obj": {
        "foo": "bar"
    }
}

Starting from RESTHeart 7.4.0, the MongoService also supports the content types application/x-www-form-urlencoded and multipart/form-data.

In those cases the request body is transformed to a BSON document by parsing the fields/parts. The example below will help make it clearer to understand how this works:

POST /coll HTTP/1.1
Content-Type: application/x-www-form-urlencoded; charset=utf-8

n=1&ns=%221%22&b=true&obj=%7B%22foo%22%3A+%22bar%22%7D

In this case, the request content (whose url-decoded value is n=1&ns="1"&b=true&obj={"foo":"bar"}) is transformed in the following document:

{
    "b": true,
    "n": 1,
    "ns": "1",
    "obj": {
        "foo": "bar"
    }
}
Note
The karate test mongoservice-multipart-form-content-type.feature includes more examples on how form-urlencoded and multipart requests are handled.

Write Mode

The default write modes for each HTTP verb are:

  • POST verb has insert write mode

  • PUT and PATCH verbs have update write mode

Use POST to create a document, PUT to replace an existing document and PATCH to update selected properties of an existing document.

The query parameter ?wm=insert|update|upsert allows specifying the write mode.

Important
the qparam ?wm is forbidden by default; to allow it, the following permission must be granted to the client (the default user admin can use it because it has the root role that provides all permissions).
{
    "_id": "user-can-wse-wm-qparam",
    "roles": [ "user" ],
    "predicate": "path-prefix(/collection)",
    "mongo": {
        "allowWriteMode": true
    }
}

Create a document

To create a document use the POST method.

POST /inventory HTTP/1.1

{ "_id": "newItem",  "item": "rubber", "qty": 15, "size": { "h": 2, "w": 1, "uom": "cm" }, "status": "A" }
Note
If _id field is not specified in the request body, it will generated by MongoDB as an ObjectId and returned to the client via the Location response header.

Replace a document

To replace a document use the PUT method.

PUT /inventory/newItem HTTP/1.1


{ "item": "pencil", "qty": 55, "size": { "h": 10, "w": 0.5, "uom": "cm" }, "status": "B", "suppliers": ["brand_1", "brand_2", "brand_3"] }

Update a document’s property

To update one or more properties of a document use the PATCH method.

PATCH /inventory/newItem HTTP/1.1

{ "status": "A" }
Note
the PATCH verb allows passing update operator expressions; the body can contain update operators.

DELETE a document

To delete a document use the DELETE method.

DELETE /inventory/newItem HTTP/1.1

Dot Notation

RESTHeart always allows using 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.

Update an array element

PATCH /inventory/newItem HTTP/1.1

{ "suppliers.1": "new_brand" }

Update the property of an embedded document

PATCH /inventory/newItem HTTP/1.1

{ "size.h": 20 }

Update with Operators

Update with operators allows applying MongoDb’s update operators to a document. For example, you can use $unset to remove a property from a document.

Note
See Update Operators in MongoDb documentation for more information.

Use the PATCH verb to update a document with update operators, passing an update operator expression document.

Note
To use update operators you need to use the verb PATCH. Anyway PUT and POST can still use the $currentDate update operator.

Example: update newItem document with update operators:

PATCH /inventory/newItem HTTP/1.1

{
  "$inc": { "qty": 1 },
  "$push": { "suppliers": "pushed_brand" },
  "$unset": { "status": null },
  "$currentDate": { "timestamp": true }
}

Update with Aggregation Pipeline

Warning
Update with Aggregation Pipeline are available from RESTHeart 7.3

Update with aggregation pipeline allows for a more expressive update statement.

Note
See Updates with Aggregation Pipeline in MongoDb documentation for more information.

Use the PATCH verb to update a document with an Aggregation Pipeline, passing an array or aggregation stages.

Example: update newItem adding two items to the current suppliers array:

PATCH /inventory/newItem HTTP/1.1

[ { "$set": { "suppliers": { "$concatArrays": [ "$suppliers", [ "brand_4", "brand_5",  ]  ] } } } ]

Bulk Write Requests

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

A bulk request response contains the URIs of the created documents.

Important
bulk requests are forbidden by default; to allow them, the following permission must be granted to the client (the default user admin can execute them because it has the root role that provides all permissions):
{
    "_id": "user-can-execute-bulk-requests",
    "roles": [ "user" ],
    "predicate": "path-prefix(/collection)",
    "mongo": {
      "allowBulkPatch": true,
      "allowBulkDelete": true,
      "allowWriteMode": true
    }
}

Create an array of documents

POST /inventory HTTP/1.1

[
   { "item": "journal", "qty": 25, "size": { "h": 14, "w": 21, "uom": "cm" }, "status": "A" },
   { "item": "notebook", "qty": 50, "size": { "h": 8.5, "w": 11, "uom": "in" }, "status": "A" },
   { "item": "paper", "qty": 100, "size": { "h": 8.5, "w": 11, "uom": "in" }, "status": "D" },
   { "item": "planner", "qty": 75, "size": { "h": 22.85, "w": 30, "uom": "cm" }, "status": "D" },
   { "item": "postcard", "qty": 45, "size": { "h": 10, "w": 15.25, "uom": "cm" }, "status": "A" }
]
Important
Its a POST request, then the default write mode is insert. As usual, you can use the ?wm=insert|update|upsert query parameter to change write mode.

Update properties in multiple documents

PATCH /inventory/*?filter={"qty":{"$gte":50}} HTTP/1.1

{
  "qty":1000
}

DELETE multiple documents

DELETE /inventory/*?filter={"qty":{"$lte":50}} HTTP/1.1

MongoDB write operations

The MongoDB write operation depends on the request method and on the write mode as follows:

write mode method URI MongoDB write operation write operation argument

insert

POST

/coll

insertOne

document

insert

PUT

/coll/docid

insertOne

document

insert

PATCH

/coll/docid

findOneAndUpdate(upsert:true) (1)

update operator expression or update aggregation pipeline

update

POST

/coll

findOneAndReplace(upsert:false)

document

update

PUT

/coll/docid

findOneAndReplace(upsert:false)

document

update

PATCH

/coll/docid

findOneAndUpdate(upsert:false)

update operator expression or update aggregation pipeline

upsert

POST

/coll

findOneAndReplace(upsert:true)

document

upsert

PUT

/coll/docid

findOneAndReplace(upsert:true)

document

upsert

PATCH

/coll/docid

findOneAndUpdate(upsert:true)

update operator expression or update aggregation pipeline

(1) uses a find condition that won’t match any existing document, making sure the operation is an insert