Navigation

Connect Over the Wire Protocol

Overview

MongoDB Stitch natively implements a subset of the MongoDB wire protocol, which allows you to connect to a Stitch application from standard MongoDB drivers and tools using a specialized connection string. Stitch supports most client features over the wire protocol, including role-based data access rules, functions, and service actions.

Compatible Clients

You can use the following tools and drivers to communicate with Stitch using a connection string:

  • Version 4.0+ of the mongo shell.
  • Any MongoDB driver that supports the appName connection string parameter. All official MongoDB drivers support this parameter in their current releases.

Enable Wire Protocol Connections

You must enable wire protocol connections in the Stitch UI before you can connect to an app with a connection string.

To enable wire protocol connections:

  • From the left-hand menu of the Stitch UI, navigate to the Atlas Clusters > Configuration page.
  • Set the toggle for MongoDB Connection String to Enabled.
  • Click Save.
../_images/enable-wire-protocol.png

Usage

Connect to Stitch with a Connection String

To connect to Stitch over the wire protocol, pass a URL-encoded Stitch connection string when you create a client, just as you would with a regular connection string.

$ mongo "mongodb://joe.schmoe%40company.com:SuperSecretPassword123@stitch.mongodb.com:27020/?authMechanism=PLAIN&authSource=%24external&ssl=true&appName=stitch-application-abcde:mongodb-atlas:local-userpass"
client = pymongo.MongoClient("mongodb://joe.schmoe%40company.com:SuperSecretPassword123@stitch.mongodb.com:27020/?authMechanism=PLAIN&authSource=%24external&ssl=true&appName=stitch-application-abcde:mongodb-atlas:local-userpass")
mongocxx::instance instance{};
mongocxx::uri uri("mongodb://joe.schmoe%40company.com:SuperSecretPassword123@stitch.mongodb.com:27020/?authMechanism=PLAIN&authSource=%24external&ssl=true&appName=stitch-application-abcde:mongodb-atlas:local-userpass");
mongocxx::client client(uri);
my $client = MongoDB::MongoClient->new(
    host => "mongodb://joe.schmoe%40company.com:SuperSecretPassword123@stitch.mongodb.com:27020/?authMechanism=PLAIN&authSource=%24external&ssl=true&appName=stitch-application-abcde:mongodb-atlas:local-userpass"
);

Perform CRUD Operations

When you’re connected to Stitch over the wire protocol you can use standard MongoDB CRUD operations. Stitch applies role-based data access rules to all queries in the context of the authenticated user specified in the connection string credentials.

> use HR
> db.employees.findOne();
{
  "_id": ObjectId("5ae782e48f25b9dc5c51c4a5"),
  "employeeId": 854271626,
  "name": {
    "first": "Lucas",
    "last": "Lewis"
  },
  "role": "PM",
  "salary": 200000,
  "email": "Lucas.Lewis.0271@company.com",
  "password": "SuperSecretPassword123",
  "manager": {
    "id": 328892725,
    "email": "Daniel.Wilson.0474@company.com",
    "name": {
      "first": "Daniel",
      "last": "Wilson"
    }
  }
}
>>> db = client["HR"]
>>> employee = db["employees"].find_one();
>>> pprint(employee)
{'_id': ObjectId('5ae782e48f25b9dc5c51c4a5'),
 'email': 'Lucas.Lewis.0271@company.com',
 'employeeId': 854271626.0,
 'manager': {'email': 'Daniel.Wilson.0474@company.com',
             'id': 328892725.0,
             'name': {'first': 'Daniel', 'last': 'Wilson'}},
 'name': {'first': 'Lucas', 'last': 'Lewis'},
 'password': 'SuperSecretPassword123',
 'role': 'PM',
 'salary': 200000}
mongocxx::database db = client["HR"];
mongocxx::collection employees = db["employees"];
bsoncxx::stdx::optional<bsoncxx::document::value> result =
    collection.find_one({});
if(result) {
    std::cout << bsoncxx::to_json(result) << "\n";
}
my $db = $client->get_database( 'HR' );
my $employees = $db->get_collection( 'employees' );
$employee = $employees->find_one();
print $employee

Call a Function

You can call functions using the callFunction database command.

> db.runCommand({
...  callFunction: "getEmployeeById",
...  arguments: ["5ae782e48f25b9dc5c51c4a5"]
...});
{
  "ok" : 1,
  "response" : {
    "_id": ObjectId("5ae782e48f25b9dc5c51c4a5"),
    "employeeId": 854271626,
    "name": {
      "first": "Lucas",
      "last": "Lewis"
    },
    "role": "PM",
    "salary": 200000,
    "email": "Lucas.Lewis.0271@company.com",
    "password": "SuperSecretPassword123",
    "manager": {
      "id": 328892725,
      "email": "Daniel.Wilson.0474@company.com",
      "name": {
        "first": "Daniel",
        "last": "Wilson"
      }
    }
  }
}
>>> function_result = db.command("callFunction", "getEmployeeById",
...     arguments=["5ae782e48f25b9dc5c51c4a5"]
...)
>>> pprint.pprint(function_result)
{'ok': 1,
 'response': {'_id': ObjectId('5ae782e48f25b9dc5c51c4a5'),
              'email': 'Lucas.Lewis.0271@company.com',
              'employeeId': 854271626.0,
              'manager': {'email': 'Daniel.Wilson.0474@company.com',
                          'id': 328892725.0,
                          'name': {'first': 'Daniel', 'last': 'Wilson'}},
              'name': {'first': 'Lucas', 'last': 'Lewis'},
              'password': 'SuperSecretPassword123',
              'role': 'PM',
              'salary': 200000}}
db.runCommand({
  callFunction: "getEmployeeById",
  arguments: ["5ae782e48f25b9dc5c51c4a5"]
});
$db->run_command([
    callFunction => "getEmployeeById",
    arguments => ["5ae782e48f25b9dc5c51c4a5"]
]);

Call a Service Function

You can call service actions using the callServiceFunction database command.

> db.runCommand({
... callServiceFunction: "get",
... service: "http",
... arguments: [{ url: "https://jsonplaceholder.typicode.com/todos/1" }]
... });
{
    "ok" : 1,
    "response" : {
            "status" : "200 OK",
            "statusCode" : 200,
            "contentLength" : NumberLong(-1),
            "headers" : {
                    "Content-Type" : ["application/json; charset=utf-8"],
                    "Connection" : ["keep-alive"],
                    "Vary" : ["Origin, Accept-Encoding"],
                    "X-Content-Type-Options" : ["nosniff"],
                    "Via" : ["1.1 vegur"],
                    "X-Powered-By" : ["Express"],
                    "Cf-Cache-Status" : ["HIT"],
                    "Expect-Ct" : ["max-age=604800, report-uri=\"https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct\""],
                        "Set-Cookie" : ["__cfduid=d7f650e765d41beb7598ce2ab62d0c0191536867096; expires=Fri, 13-Sep-19 19:31:36 GMT; path=/; domain=.typicode.com; HttpOnly"],
                    "Access-Control-Allow-Credentials" : ["true"],
                    "Cache-Control" : ["public, max-age=14400"],
                    "Pragma" : ["no-cache"],
                    "Etag" : ["W/\"53-hfEnumeNh6YirfjyjaujcOPPT+s\""],
                    "Server" : ["cloudflare"],
                    "Cf-Ray" : ["459d08f88e1e56db-IAD"],
                    "Date" : ["Thu, 13 Sep 2018 19:31:36 GMT"],
                    "Expires" : ["Thu, 13 Sep 2018 23:31:36 GMT"]
                },
                "cookies" : {
                    "__cfduid" : {
                            "value" : "d7f650e765d41beb7598ce2ab62d0c0191536867096",
                            "path" : "/",
                            "domain" : ".typicode.com",
                            "expires" : "Mon, 01 Jan 0001 00:00:00 GMT",
                            "maxAge" : 0,
                            "secure" : false,
                            "httpOnly" : true
                    }
                },
                "body" : BinData(0,"ewogICJ1c2VySWQiOiAxLAogICJpZCI6IDEsCiAgInRpdGxlIjogImRlbGVjdHVzIGF1dCBhdXRlbSIsCiAgImNvbXBsZXRlZCI6IGZhbHNlCn0=")
    }
}
>>> result = db.command("callServiceFunction", "get",
...    service="http",
...    arguments=[{"url": "https://jsonplaceholder.typicode.com/todos/1"}]
...)
>>> pprint.pprint(result)
{'ok': 1,
 'response': {'body': b'{\n  "userId": 1,\n  "id": 1,\n  "title": "delectus aut'
                      b' autem",\n  "completed": false\n}',
              'contentLength': -1,
              'cookies': {'__cfduid': {'domain': '.typicode.com',
                                       'expires': 'Mon, 01 Jan 0001 00:00:00 '
                                                  'GMT',
                                       'httpOnly': True,
                                       'maxAge': 0,
                                       'path': '/',
                                       'secure': False,
                                       'value': 'd4b10004e96ca7fee0be03dceebaf2ab71536866400'}},
              'headers': {'Access-Control-Allow-Credentials': ['true'],
                          'Cache-Control': ['public, max-age=14400'],
                          'Cf-Cache-Status': ['HIT'],
                          'Cf-Ray': ['459cf7fc7e20c1bd-IAD'],
                          'Connection': ['keep-alive'],
                          'Content-Type': ['application/json; charset=utf-8'],
                          'Date': ['Thu, 13 Sep 2018 19:20:00 GMT'],
                          'Etag': ['W/"53-hfEnumeNh6YirfjyjaujcOPPT+s"'],
                          'Expect-Ct': ['max-age=604800, '
                                        'report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct"'],
              'Expires': ['Thu, 13 Sep 2018 23:20:00 GMT'],
              'Pragma': ['no-cache'],
              'Server': ['cloudflare'],
              'Set-Cookie': ['__cfduid=d4b10004e96ca7fee0be03dceebaf2ab71536866400; '
                             'expires=Fri, 13-Sep-19 19:20:00 GMT; '
                             'path=/; domain=.typicode.com; '
                             'HttpOnly'],
              'Vary': ['Origin, Accept-Encoding'],
              'Via': ['1.1 vegur'],
              'X-Content-Type-Options': ['nosniff'],
              'X-Powered-By': ['Express']},
  'status': '200 OK',
  'statusCode': 200}}
db.runCommand({
  callServiceFunction: "get",
  service: "http",
  arguments: [{ url: "https://jsonplaceholder.typicode.com/todos/1" }]
});
$db->run_command([
    callServiceFunction => "get",
    service => "http",
    arguments => ["https://jsonplaceholder.typicode.com/todos/1"]
]);

Get the Logged In User’s Data

You can get the user object for the authenticated user using the userProfile database command.

> db.runCommand({ userProfile: 1 });
{
    "ok" : 1,
    "profile" : {
            "userid" : "5ad7a79e8f25b975898d77b8",
            "domainid" : ObjectId("5ad7a69746224c054067c8b1"),
            "identities" : [
                    {

                    }
            ],
            "data" : "{\"email\":\"joe.schmoe@company.com\"}",
            "type" : "normal",
            "roleassignments" : [ ]
    }
}
>>> result = db.command("userProfile", 1)
>>> pprint.pprint(result)
{'ok': 1,
 'profile': {'data': '{"email":"joe.schmoe@company.com"}',
             'domainid': ObjectId('5ad7a69746224c054067c8b1'),
             'identities': [{}],
             'roleassignments': [],
             'type': 'normal',
             'userid': '5ad7a79e8f25b975898d77b8'}}
db.runCommand({ userProfile: 1 });
$db->run_command([userProfile => 1]);

Reference

Database Commands

The Stitch wire protocol includes several database commands that you can use to call functions, interact with services, and access the logged in user’s data.

Command Description Prototype
callFunction Calls the specified function and returns any result.
{
  callFunction: <function name>,
  arguments: [<arg1>, <arg2>, ...]
}
callServiceFunction Calls the specified service action and returns any result.
{
  callServiceFunction: <function name>,
  service: <service name>,
  arguments: [<arg1>, <arg2>, ...]
}
userProfile Returns the user object for the authenticated user.
{
  userProfile: 1
}

Unsupported Functionality

Connections to Stitch over the wire protocol have access to the full functionality of the MongoDB Service; however, Stitch does not support all operations and features available in standard tools and clients.

The following notable features are not supported:

Command Fields

The following table lists database command fields that are not supported when connected to Stitch over the wire protocol:

Command Unsupported Fields
find
  • hint
  • skip
  • batchSize
  • comment
  • maxScan
  • maxTimeMS
  • readConcern
  • max
  • min
  • returnKey
  • showRecordId
  • tailable
  • awaitData
  • oplogReplay
  • noCursorTimeout
  • allowPartialResults
  • collation
aggregate
  • explain
  • allowDiskUse
  • maxTimeMS
  • readConcern
  • collation
  • bypassDocumentValidation
  • hint
  • comment
  • writeConcern
count
  • limit
  • skip
  • hint
  • readConcern
delete
  • collation
insert
  • writeConcern
  • bypassDocumentValidation
update
  • bypassDocumentValidation
  • collation
  • arrayFilters