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 through one of its linked MongoDB clusters using standard MongoDB drivers and tools. Clients use a specialized Stitch connection string to connect and send requests. Stitch supports most client features over the wire protocol, including role-based data access rules, functions, and service actions.

Prerequisites

You must enable wire protocol connections for one or more linked clusters in your application before you can connect over the wire protocol.

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.

Note

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. For details, see MongoDB Service Limitations.

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.

Command Description Prototype
callFunction
Calls the specified function and returns any result.
{
  callFunction: <function name>,
  arguments: [<arg1>, <arg2>, ...]
}
> 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.

Command Description Prototype
callServiceFunction
Calls the specified service action and returns any result.
{
  callServiceFunction: <function name>,
  service: <service name>,
  arguments: [<arg1>, <arg2>, ...]
}
> 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.

Command Description Prototype
userProfile
Returns the user object for the authenticated user.
{
  userProfile: 1
}
> 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]);