Examples of the WebSocket API
🔧 Configuration
The following requests create a collection with three change streams:
-
all bound at
/messages/_streams/all
-
mine bound at
/messages/_streams/mine
cURL
curl -i -X PUT '[INSTANCE-URL]/messages' \
-H 'Authorization: Basic [BASIC-AUTH]' \
-H 'Content-Type: application/json' \
-d '{
"streams" : [
{ "stages" : [
{
"_$match": {
"_$or" : [ { "operationType": "insert" }, { "operationType": "update" } ]
}
}
],
"uri" : "all"
},
{ "stages" : [
{ "_$match" : { "fullDocument::name" : { "_$var" : "n" } } }
],
"uri" : "mine"
}
]
}'
HTTPie
echo '{
"streams" : [
{ "stages" : [
{
"_$match": {
"_$or" : [ { "operationType": "insert" }, { "operationType": "update" } ]
}
}
],
"uri" : "all"
},
{ "stages" : [
{ "_$match" : { "fullDocument::name" : { "_$var" : "n" } } }
],
"uri" : "mine"
}
]
}' | http PUT [INSTANCE-URL]/messages \
'Authorization:Basic [BASIC-AUTH]' \
'Content-Type:application/json'
JavaScript
fetch('[INSTANCE-URL]/messages', {
method: 'PUT',
headers: {
'Authorization': 'Basic [BASIC-AUTH]',
'Content-Type': 'application/json'
},
body: JSON.stringify({
"streams" : [
{ "stages" : [
{
"_$match": {
"_$or" : [ { "operationType": "insert" }, { "operationType": "update" } ]
}
}
],
"uri" : "all"
},
{ "stages" : [
{ "_$match" : { "fullDocument::name" : { "_$var" : "n" } } }
],
"uri" : "mine"
}
]
})
})
.then(response => {
if (!response.ok) throw new Error(`HTTP ${response.status}`);
return response.json();
})
.then(data => console.log(data))
.catch(error => console.error('Error:', error));
Note
|
The request body is included in the examples above. |
Note that the $match
stage specifies a condition on the name
property using fullDocument::name
.
This is because the Change Event looks like:
{
"fullDocument": {
"_id": { "$oid": "5e15ff5779ca449eb20fdd09" },
"message": "hi uji, how are you?",
"name": "uji",
"_etag": { "$oid": "5e15ff57a2e5700c3459e801" }
},
"documentKey": {
"_id": { "$oid": "5e15ff5779ca449eb20fdd09" }
},
"updateDescription": null,
"operationType": "insert"
}
Note the _links
collection property showing the URIs of the change streams (returned with ?rep=SHAL
).
cURL
curl -i -X GET '[INSTANCE-URL]/messages?rep=SHAL' \
-H 'Authorization: Basic [BASIC-AUTH]'
HTTPie
http GET [INSTANCE-URL]/messages rep==SHAL \
'Authorization:Basic [BASIC-AUTH]'
JavaScript
fetch('[INSTANCE-URL]/messages?rep=SHAL', {
method: 'GET',
headers: {
'Authorization': 'Basic [BASIC-AUTH]'
}
})
.then(response => {
if (!response.ok) throw new Error(`HTTP ${response.status}`);
return response.json();
})
.then(data => console.log(data))
.catch(error => console.error('Error:', error));
{
"_links": {
"all": {
"href": "/messages/_streams/all"
},
"mine": {
"href": "/messages/_streams/mine"
}
}
}
Alternatively, you can define a single change stream that returns either all messages or only those sent by a specific name
. This can be achieved using optional stages:
{
"streams" : [
{ "stages" : [
{ "$ifvar": [ "n", { "_$match" : { "fullDocument::name" : { "_$var" : "n" } } } ] }
],
"uri" : "withOptionalStage"
}
]
}
To subscribe to the change streams, we’ll use websocat
, a command-line client for WebSockets, like netcat (or curl) for ws://
Tip
|
You can install websocat following the instructions at https://github.com/vi/websocat#installation or downloading binaries from https://github.com/vi/websocat/releases
|
Connect to the change streams using the following command (assuming the default user admin
exists with the default password):
$ websocat --text - autoreconnect:ws://admin:secret@127.0.0.1:8080/messages/_streams/all
To allow connections without authentication, you can define the following permission
cURL
curl -i -X POST '[INSTANCE-URL]/acl' \
-H 'Authorization: Basic [BASIC-AUTH]' \
-H 'Content-Type: application/json' \
-d '{
"_id": "unauthenticatedCanConnectToMyWebSocket",
"predicate": "path-prefix('"'"'/messages/_streams/all'"'"')",
"priority": 0,
"roles": [ "$unauthenticated" ]
}'
HTTPie
echo '{
"_id": "unauthenticatedCanConnectToMyWebSocket",
"predicate": "path-prefix('"'"'/messages/_streams/all'"'"')",
"priority": 0,
"roles": [ "$unauthenticated" ]
}' | http POST [INSTANCE-URL]/acl \
'Authorization:Basic [BASIC-AUTH]' \
'Content-Type:application/json'
JavaScript
fetch('[INSTANCE-URL]/acl', {
method: 'POST',
headers: {
'Authorization': 'Basic [BASIC-AUTH]',
'Content-Type': 'application/json'
},
body: JSON.stringify({
"_id": "unauthenticatedCanConnectToMyWebSocket",
"predicate": "path-prefix('/messages/_streams/all')",
"priority": 0,
"roles": [ "$unauthenticated" ]
})
})
.then(response => {
if (!response.ok) throw new Error(`HTTP ${response.status}`);
return response.json();
})
.then(data => console.log(data))
.catch(error => console.error('Error:', error));
With this permission in place, you can connect to the WebSocket without authentication:
$ websocat --text - autoreconnect:ws://127.0.0.1:8080/messages/_streams/all
If you now create a new document in the collection messages
cURL
curl -i -X POST '[INSTANCE-URL]/messages' \
-H 'Authorization: Basic [BASIC-AUTH]' \
-H 'Content-Type: application/json' \
-d '{
"message": "Hello WebSockets!",
"name": "uji"
}'
HTTPie
echo '{
"message": "Hello WebSockets!",
"name": "uji"
}' | http POST [INSTANCE-URL]/messages \
'Authorization:Basic [BASIC-AUTH]' \
'Content-Type:application/json'
JavaScript
fetch('[INSTANCE-URL]/messages', {
method: 'POST',
headers: {
'Authorization': 'Basic [BASIC-AUTH]',
'Content-Type': 'application/json'
},
body: JSON.stringify({
"message": "Hello WebSockets!",
"name": "uji"
})
})
.then(response => {
if (!response.ok) throw new Error(`HTTP ${response.status}`);
return response.json();
})
.then(data => console.log(data))
.catch(error => console.error('Error:', error));
You get the following output from websocat
:
$ websocat --text - autoreconnect:ws://admin:secret@127.0.0.1:8080/messages/_streams/all
{"fullDocument":{"_id":{"$oid":"62166d53ebdcd56455a1a7ab"},"message":"Hello WebSockets!","name":"uji","_etag":{"$oid":"62166d53ebdcd56455a1a7aa"}},"documentKey":{"_id":{"$oid":"62166d53ebdcd56455a1a7ab"}},"operationType":"insert"}