Writing Documents RESTHeart Cloud
This page explains how to create, update, and delete MongoDB documents through RESTHeart’s REST API.
🔧 Configuration
⚡ Setup Guide
To run the examples on this page, you need a RESTHeart instance.
Option 1: Use RESTHeart Cloud (Recommended)
The fastest way to get started is with RESTHeart Cloud. Create a free service in minutes:
-
Sign up at cloud.restheart.com
-
Create a free API service
-
Set up your root user following the Root User Setup guide
-
Use the configuration panel above to set your service URL and credentials
|
Tip
|
All code examples on this page will automatically use your configured RESTHeart Cloud credentials. |
Option 2: Run RESTHeart Locally
If you prefer local development, follow the Setup Guide to install RESTHeart on your machine.
|
Note
|
Local instances run at http://localhost:8080 with default credentials admin:secret
|
Create the Inventory Collection
The example requests on this page use the inventory collection. If not already created, run the following:
cURL
curl -i -X PUT [INSTANCE-URL]/inventory -H "Authorization: Basic [BASIC-AUTH]"
curl -i -X POST [INSTANCE-URL]/inventory?wm=upsert -H "Authorization: Basic [BASIC-AUTH]" \
-d '[
{ "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" }
]'
HTTPie
http PUT [INSTANCE-URL]/inventory Authorization:"Basic [BASIC-AUTH]"
echo '[
{ "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" }
]' | http POST [INSTANCE-URL]/inventory wm==upsert Authorization:"Basic [BASIC-AUTH]"
JavaScript
const data = [
{ "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" }
];
await fetch('[INSTANCE-URL]/inventory', {
method: 'PUT',
headers: { 'Authorization': 'Basic [BASIC-AUTH]' }
});
await fetch('[INSTANCE-URL]/inventory?wm=upsert', {
method: 'POST',
body: JSON.stringify(data),
headers: { 'Authorization': 'Basic [BASIC-AUTH]' }
});
HTTP Methods for Writing Data
RESTHeart uses standard HTTP methods for database operations:
| HTTP Method | Purpose |
|---|---|
POST |
Create new documents (generates a new ID if not specified) |
PUT |
Replace existing documents or create with specified ID |
PATCH |
Update specific fields in existing documents |
DELETE |
Remove documents |
Content Types
JSON Format (Default)
For write operations, the default content type is application/json:
POST /inventory HTTP/1.1
Content-Type: application/json
{
"name": "Product XYZ",
"price": 99.99,
"available": true,
"details": {
"color": "red",
"size": "medium"
}
}
Form Data Support
You can also use the following formats (Content-Type):
-
application/x-www-form-urlencoded -
multipart/form-data
These formats are automatically converted to JSON documents:
POST /collection HTTP/1.1
Content-Type: application/x-www-form-urlencoded; charset=utf-8
name=Product%20XYZ&price=99.99&available=true&details=%7B%22color%22%3A%22red%22%2C%22size%22%3A%22medium%22%7D
Creating Documents
POST - Create with Generated ID
Use POST to create a document and let MongoDB generate an ObjectId:
cURL
curl -i -X POST [RESTHEART-URL]/inventory \
-H "Authorization: Basic [BASIC-AUTH]" \
-H "Content-Type: application/json" \
-d '{
"item": "rubber",
"qty": 15,
"size": {
"h": 2,
"w": 1,
"uom": "cm"
},
"status": "A"
}'
HTTPie
http POST [RESTHEART-URL]/inventory \
Authorization:"Basic [BASIC-AUTH]" \
item="rubber" \
qty:=15 \
size:='{"h": 2, "w": 1, "uom": "cm"}' \
status="A"
JavaScript
fetch('[RESTHEART-URL]/inventory', {
method: 'POST',
headers: {
'Authorization': 'Basic [BASIC-AUTH]',
'Content-Type': 'application/json'
},
body: JSON.stringify({
item: "rubber",
qty: 15,
size: {
h: 2,
w: 1,
uom: "cm"
},
status: "A"
})
})
.then(response => {
if (response.ok) {
console.log('Resource created successfully');
console.log('Location:', response.headers.get('Location'));
} else {
console.error('Failed to create resource:', response.status);
}
})
.catch(error => console.error('Error:', error));
The response includes a Location header with the new document’s URI:
HTTP/1.1 201 Created
Location: http://localhost:8080/inventory/61709f718bedc3055e218d7e
|
Tip
|
You can specify your own _id in the request body to avoid having MongoDB generate one.
|
PUT - Create with Specific ID
Use PUT with the ?wm=upsert parameter to create a document with a specific ID:
cURL
curl -i -X PUT "[RESTHEART-URL]/inventory/myCustomId?wm=upsert" \
-H "Authorization: Basic [BASIC-AUTH]" \
-H "Content-Type: application/json" \
-d '{
"item": "pencil",
"qty": 55,
"size": {
"h": 10,
"w": 0.5,
"uom": "cm"
}
}'
HTTPie
http PUT "[RESTHEART-URL]/inventory/myCustomId?wm=upsert" \
Authorization:"Basic [BASIC-AUTH]" \
item="pencil" \
qty:=55 \
size:='{"h": 10, "w": 0.5, "uom": "cm"}'
JavaScript
fetch('[RESTHEART-URL]/inventory/myCustomId?wm=upsert', {
method: 'PUT',
headers: {
'Authorization': 'Basic [BASIC-AUTH]',
'Content-Type': 'application/json'
},
body: JSON.stringify({
item: "pencil",
qty: 55,
size: {
h: 10,
w: 0.5,
uom: "cm"
}
})
})
.then(response => {
if (response.ok) {
console.log('Resource created successfully');
console.log('Location:', response.headers.get('Location'));
} else {
console.error('Failed to create resource:', response.status);
}
})
.catch(error => console.error('Error:', error));
Updating Documents
PUT - Replace Document
PUT replaces an existing document completely:
PUT /inventory/myCustomId HTTP/1.1
{
"item": "pencil",
"qty": 60,
"size": {
"h": 15,
"w": 0.5,
"uom": "cm"
}
}
|
Warning
|
This replaces the entire document. Any fields not included in the request will be removed. |
PATCH - Update Specific Fields
PATCH modifies only the specified fields:
cURL
curl -i -X PATCH [RESTHEART-URL]/inventory/myCustomId \
-H "Authorization: Basic [BASIC-AUTH]" \
-H "Content-Type: application/json" \
-d '{
"qty": 75,
"status": "B"
}'
HTTPie
http PATCH [RESTHEART-URL]/inventory/myCustomId \
Authorization:"Basic [BASIC-AUTH]" \
qty:=75 \
status="B"
JavaScript
fetch('[RESTHEART-URL]/inventory/myCustomId', {
method: 'PATCH',
headers: {
'Authorization': 'Basic [BASIC-AUTH]',
'Content-Type': 'application/json'
},
body: JSON.stringify({
qty: 75,
status: "B"
})
})
.then(response => {
if (response.ok) {
console.log('Write request executed successfully');
} else {
console.error('Write request failed:', response.status);
}
})
.catch(error => console.error('Error:', error));
This only updates the qty and status fields, leaving all other fields unchanged.
Advanced Update Techniques
Updating Nested Fields with Dot Notation
Access nested document fields and array elements using dot notation:
cURL
curl -i -X PATCH [RESTHEART-URL]/inventory/myCustomId \
-H "Authorization: Basic [BASIC-AUTH]" \
-H "Content-Type: application/json" \
-d '{
"size.h": 20
}'
HTTPie
http PATCH [RESTHEART-URL]/inventory/myCustomId \
Authorization:"Basic [BASIC-AUTH]" \
size.h:=20
JavaScript
fetch('[RESTHEART-URL]/inventory/myCustomId', {
method: 'PATCH',
headers: {
'Authorization': 'Basic [BASIC-AUTH]',
'Content-Type': 'application/json'
},
body: JSON.stringify({
"size.h": 20
})
})
.then(response => {
if (response.ok) {
console.log('Write request executed successfully');
} else {
console.error('Write request failed:', response.status);
}
})
.catch(error => console.error('Error:', error));
This updates only the height property within the size object.
For array elements:
cURL
curl -i -X PATCH [RESTHEART-URL]/inventory/myCustomId \
-H "Authorization: Basic [BASIC-AUTH]" \
-H "Content-Type: application/json" \
-d '{
"tags.1": "office"
}'
HTTPie
http PATCH [RESTHEART-URL]/inventory/myCustomId \
Authorization:"Basic [BASIC-AUTH]" \
tags.1="office"
JavaScript
fetch('[RESTHEART-URL]/inventory/myCustomId', {
method: 'PATCH',
headers: {
'Authorization': 'Basic [BASIC-AUTH]',
'Content-Type': 'application/json'
},
body: JSON.stringify({
"tags.1": "office"
})
})
.then(response => {
if (response.ok) {
console.log('Write request executed successfully');
} else {
console.error('Write request failed:', response.status);
}
})
.catch(error => console.error('Error:', error));
This updates the second element of the tags array.
MongoDB Update Operators
Use MongoDB’s update operators in PATCH requests for more complex updates:
cURL
curl -i -X PATCH [RESTHEART-URL]/inventory/myCustomId \
-H "Authorization: Basic [BASIC-AUTH]" \
-H "Content-Type: application/json" \
-d '{
"$inc": { "qty": 1 },
"$push": { "tags": "school" },
"$unset": { "discontinued": "" },
"$currentDate": { "lastModified": true }
}'
HTTPie
http PATCH [RESTHEART-URL]/inventory/myCustomId \
Authorization:"Basic [BASIC-AUTH]" \
Content-Type:application/json \
'\$inc:={"qty": 1}' \
'\$push:={"tags": "school"}' \
'\$unset:={"discontinued": ""}' \
'\$currentDate:={"lastModified": true}'
JavaScript
fetch('[RESTHEART-URL]/inventory/myCustomId', {
method: 'PATCH',
headers: {
'Authorization': 'Basic [BASIC-AUTH]',
'Content-Type': 'application/json'
},
body: JSON.stringify({
"$inc": { "qty": 1 },
"$push": { "tags": "school" },
"$unset": { "discontinued": "" },
"$currentDate": { "lastModified": true }
})
})
.then(response => {
if (response.ok) {
console.log('Write request executed successfully');
} else {
console.error('Write request failed:', response.status);
}
})
.catch(error => console.error('Error:', error));
This:
- Increments qty by 1
- Adds "school" to the tags array
- Removes the discontinued field
- Sets lastModified to the current date/time
|
Tip
|
See MongoDB Update Operators for all available operators. |
Aggregation Pipeline Updates
Since RESTHeart 7.3, you can use MongoDB’s aggregation pipeline for updates:
PATCH /inventory/myCustomId HTTP/1.1
[
{
"$set": {
"tags": {
"$concatArrays": ["$tags", ["office", "school"]]
}
}
}
]
This adds "office" and "school" to the existing tags array.
Deleting Documents
Use the DELETE method to remove documents:
cURL
curl -i -X DELETE [RESTHEART-URL]/inventory/myCustomId \
-H "Authorization: Basic [BASIC-AUTH]"
HTTPie
http DELETE [RESTHEART-URL]/inventory/myCustomId \
Authorization:"Basic [BASIC-AUTH]"
JavaScript
fetch('[RESTHEART-URL]/inventory/myCustomId', {
method: 'DELETE',
headers: {
'Authorization': 'Basic [BASIC-AUTH]'
}
})
.then(response => {
if (response.ok) {
console.log('Write request executed successfully');
} else {
console.error('Write request failed:', response.status);
}
})
.catch(error => console.error('Error:', error));
Bulk Operations
Perform operations on multiple documents with a single request.
Bulk Inserts
Create multiple documents at once:
cURL
curl -i -X POST [RESTHEART-URL]/inventory \
-H "Authorization: Basic [BASIC-AUTH]" \
-H "Content-Type: application/json" \
-d '[
{ "item": "journal", "qty": 25, "status": "A" },
{ "item": "notebook", "qty": 50, "status": "A" },
{ "item": "paper", "qty": 100, "status": "D" },
{ "item": "planner", "qty": 75, "status": "D" },
{ "item": "postcard", "qty": 45, "status": "A" }
]'
HTTPie
echo '[
{ "item": "journal", "qty": 25, "status": "A" },
{ "item": "notebook", "qty": 50, "status": "A" },
{ "item": "paper", "qty": 100, "status": "D" },
{ "item": "planner", "qty": 75, "status": "D" },
{ "item": "postcard", "qty": 45, "status": "A" }
]' | http POST [RESTHEART-URL]/inventory \
Authorization:"Basic [BASIC-AUTH]" \
Content-Type:application/json
JavaScript
fetch('[RESTHEART-URL]/inventory', {
method: 'POST',
headers: {
'Authorization': 'Basic [BASIC-AUTH]',
'Content-Type': 'application/json'
},
body: JSON.stringify([
{ item: "journal", qty: 25, status: "A" },
{ item: "notebook", qty: 50, status: "A" },
{ item: "paper", qty: 100, status: "D" },
{ item: "planner", qty: 75, status: "D" },
{ item: "postcard", qty: 45, status: "A" }
])
})
.then(response => {
if (response.ok) {
console.log('Resource created successfully');
console.log('Location:', response.headers.get('Location'));
} else {
console.error('Failed to create resource:', response.status);
}
})
.catch(error => console.error('Error:', error));
Bulk Updates
Update multiple documents using a filter:
cURL
curl -i -X PATCH '[RESTHEART-URL]/inventory/*' \
-G --data-urlencode 'filter={"qty":{"$gt":50}}' \
-H "Authorization: Basic [BASIC-AUTH]" \
-H "Content-Type: application/json" \
-d '{
"highQuantity": true
}'
HTTPie
http PATCH '[RESTHEART-URL]/inventory/*?filter={"qty":{"$gt":50}}' \
Authorization:"Basic [BASIC-AUTH]" \
highQuantity:=true
JavaScript
fetch('[RESTHEART-URL]/inventory/*?filter=' + encodeURIComponent('{"qty":{"$gt":50}}'), {
method: 'PATCH',
headers: {
'Authorization': 'Basic [BASIC-AUTH]',
'Content-Type': 'application/json'
},
body: JSON.stringify({
highQuantity: true
})
})
.then(response => {
if (response.ok) {
console.log('Write request executed successfully');
} else {
console.error('Write request failed:', response.status);
}
})
.catch(error => console.error('Error:', error));
This adds the highQuantity field to all documents with a quantity greater than 50.
Bulk Deletes
Delete multiple documents matching a filter:
cURL
curl -i -X DELETE '[RESTHEART-URL]/inventory/*' \
-G --data-urlencode 'filter={"status":"D"}' \
-H "Authorization: Basic [BASIC-AUTH]"
HTTPie
http DELETE '[RESTHEART-URL]/inventory/*?filter={"status":"D"}' \
Authorization:"Basic [BASIC-AUTH]"
JavaScript
fetch('[RESTHEART-URL]/inventory/*?filter=' + encodeURIComponent('{"status":"D"}'), {
method: 'DELETE',
headers: {
'Authorization': 'Basic [BASIC-AUTH]'
}
})
.then(response => {
if (response.ok) {
console.log('Write request executed successfully');
} else {
console.error('Write request failed:', response.status);
}
})
.catch(error => console.error('Error:', error));
This deletes all documents with a status of "D".
|
Important
|
Bulk operations require special permissions. The default admin user can execute them, but other users need the appropriate permissions.
|
Write Modes
The ?wm= query parameter can override the default write mode for each HTTP method:
| Write Mode | Description | Example |
|---|---|---|
insert |
Create a new document, fail if ID exists |
|
update |
Update an existing document, fail if ID doesn’t exist |
|
upsert |
Update if exists, create if doesn’t exist |
|
|
Important
|
The wm parameter requires special permissions. The default admin user can use it, but other users need the allowWriteMode permission.
|
Reference: Default MongoDB Operations
This table shows which MongoDB operation is executed based on the HTTP method and write mode:
| Write Mode | Method | URI | MongoDB Operation | Description |
|---|---|---|---|---|
insert |
POST |
|
|
Create document with generated ID |
insert |
PUT |
|
|
Create document with specified ID |
insert |
PATCH |
|
|
Insert with update operators |
update |
POST |
|
|
Replace existing document |
update |
PUT |
|
|
Replace existing document |
update |
PATCH |
|
|
Update specific fields |
upsert |
POST |
|
|
Replace or create with body ID |
upsert |
PUT |
|
|
Replace or create with URI ID |
upsert |
PATCH |
|
|
Update fields or create |
Bold entries indicate default behavior when no wm parameter is specified.