Navigation

Functions

➤ Functions are written in Javascript.
  • ECMAScript 6 features (e.g. const and let) are not supported.
  • Functions do not continue execution after returning. There are no event listeners or asynchronous callbacks.
  • Functions return values as BSON. See BSON for more information.
➤ Functions are written in the function editor and referenced by name.

Stitch functions run the Javascript function assigned to exports. All Stitch functions are required to assign a Javascript function to exports.

Stitch functions may be called from other Stitch functions or from the Javascript SDK.

Stitch functions may be called from other Stitch functions or from the Android SDK.

Stitch functions may be called from other Stitch functions or from the iOS SDK.

For example, assume the Stitch function named “increment” is defined as follows:

exports = function (arg) { return arg + 1; };

The Stitch function named “increment” can be called from another Stitch function as follows:

context.functions.execute("increment", 1); // returns 2

These functions can be debugged using the Console at the bottom of the Function Editor tab. For more information on the debug console, see Debug Console.

The Stitch function named “increment” can be called from the client SDK as follows:

stitchClient.executeFunction("increment", 1).then(/* ... */);
stitchClient.executeFunction("increment", 1).addOnCompleteListener(/* ... */);
stitchClient.executeFunction("increment", args: 1).response(/* ... */);
➤ Functions use context to access services and other contextual information.
  • Services like Twilio or GitHub can be accessed through context.services.
  • Functions can execute other functions using context.functions.
  • Information about the requesting user can be accessed through context.user.
  • Information about the HTTP request that triggered a function call can be accessed through context.request.
  • Global variables can be defined in Stitch and referenced with context.values.

The following example function queries MongoDB via Stitch and sends a text message to each user through a Twilio service called “my-twilio-service”.

exports = function(message){
    var mongodb = context.services.get("mongodb-atlas");
    var twilio = context.services.get("my-twilio-service");
    var coll = mongodb.db("db").collection("users");
    var users = coll.find().toArray();
    users.forEach(function(user){
       twilio.send({
           to: user.phone,
           from: context.values.get("twilioNumber"),
           body: message
       });
   });
};

For more information on the context object, see Function Context.

Defining Functions

Use the following procedure to define a function in the MongoDB Stitch console:

  1. Select your MongoDB Stitch app in the console. If you haven’t yet created a MongoDB Stitch app, see Getting Started.

  2. Click Functions in the left navigation pane.

  3. Click New Function in the Functions view.

  4. Enter a name for the function in the Name field. The name must be unique within the MongoDB Stitch app where it is defined.

  5. You can specify any of the following function properties:

    Property Description
    Private If selected, the function may be called only from incoming webhooks, rules, and other functions defined in the MongoDB Stitch Admin console. Private functions may not be called from MongoDB Stitch client applications.
    Can Evaluate An expression in the format of a JSON document that must evaluate to true before the function may run. The expression can include expansions. An empty JSON document always evaluates to true, indicating that the function can always be run. This function-specific expression is evaluated before other service-specific rules.
  6. Write the function code.

  7. Click Done.

  8. Click Save to save the function.

Debug Console

MongoDB Stitch provides an interface that you can use to test and debug functions. In the Function Editor tab, there are two tabs below the JavaScript editor that are marked Console and Result.

Use the following procedure to run a function in the debug console:

  1. In the Console tab, type exports to call the current function in the editor. You can call exports with or without arguments.

    exports(); // calls the function with no arguments
    
    exports("hello world"); // calls the function with argument "hello world"
    

    Note

    exports() will execute the function as it is currently written in the editor, not as it was saved. To run the saved version of the function, use context.functions.execute("<function_name>""). You can also use context.functions.execute("<function_name>"") to call other saved functions.

    You can also define additional code in the console to emulate how you would call the function in your client application or to debug more complex scenarios.

    my_arguments = context.functions.execute("some_other_function");
    exports(my_arguments); // calls the function with the result of another function
    
  2. Specify a user to run the function. By clicking on Select User, you can choose any user that has authenticated with your MongoDB Stitch application. The selected user determines who the debug console will be impersonating when it runs the function. The MongoDB rules and other service rules that affect that user will apply, and the context.user object available in the function will represent that user.

  3. Run the function by clicking Run Function as. The result will be displayed in Result tab of the debug console. The result will be expressed as MongoDB extended JSON, which expresses BSON documents in a strict JSON format. Additionally, any console.log, console.warn, and console.error calls display their output in the Result tab. For example, if the function editor has the following content:

    exports = function(arg1) {
       console.log(arg1);
       return { "arg": arg1 };
    };
    

    And the console calls the function with:

    exports("hello world");
    

    When run, the result may look like the following:

    > ran on Wed Dec 06 2017 13:57:34 GMT-0500 (EST)
    > took 302.14µs
    > logs:
    hello world
    > result:
    {
      "arg": "hello world"
    }
    > result (JavaScript):
    EJSON.parse('{"arg":"hello world"}')
    

    Under result:, the function result is expressed in extended JSON. Under result (JavaScript):, there is a line of JavaScript code that you can copy that will produce the actual JavaScript object that the function returned. This may be useful if you want to further debug the result of the function in the console or in another function.

    Note

    If there are multiple function calls specified in the Console tab, only the result of the last function call will be displayed in the Result tab. However, logs from all console.log, console.warn, and console.error calls made in any function calls will be included.

Function Context

The context variable contains the following.

Property Description
context.services Access to functions provided by Services.
context.values Access to variables defined in the Stitch console. See Values.
context.user Information about the requesting user, including the type of authorization.
context.request Information about the HTTP request that triggered this function call.
context.functions Access to execute other functions.

For more information see Function Context.

Calling Other Functions

To call a separate function from within a function, use context.functions. Suppose the function sum is defined as follows:

exports = function (a, b) {
    return a + b;
};

This can be called from another function difference as follows:

exports = function(a, b) {
    return context.functions.execute("sum", a, -1 * b);
};

Return Values

Functions return values as extended JSON. Consider the following function named return_something.

exports = function(arg) {
    return {a : 1, b: false, c: "hello"};
};

Calling return_something from the client SDK receives the result as extended JSON.

stitchClient.executeFunction("return_something").then(
function(result) {
    console.log(JSON.stringify(result));
    // prints {"a": "1", "b": false, "c": "hello"}
})

Services

Services have easy-to-use functions which interact with their APIs. For more information see Services. For a complete reference on available service functions see the APIs.

Service Description Basic Example
MongoDB Atlas Interact with a MongoDB database.
exports = function() {
    var mongodb = context.services.get("mongodb-atlas");
    var coll = mongodb.db("db").collection("coll");
    return coll.findOne({});
};
Amazon S3 Store data.
exports = function() {
    var s3 = context.services.get("my-s3-service");
    return s3.put({
       "body": "Hello world!",
       "contentType": "text/plain",
       "acl": "public-read",
       "bucket": "my-bucket-name",
       "key": "test-object"
    });
};
Amazon SES Send email.
exports = function() {
    var ses = context.services.get("my-ses-service");
    ses.send({
      "fromAddress": "no-reply@example.com",
      "toAddress": "email@example.com",
      "subject": "Test",
      "body": "Hello world!"});
};
HTTP Make HTTP requests.
exports = function() {
    var http = context.services.get("my-http-service");
    return http.get({url: "http://google.com"});
};
Twilio Send and receive text messages.
exports = function() {
    var twilio = context.services.get("my-twilio-service");
    twilio.send({
        to: "+15558901234",
        from: context.values.get("twilioNumber"),
        body: "Hello world!"
    });
};

Clients

You can call the function from your application client to execute the function.

To execute a function, use the StitchClient.executeFunction() method, passing the function name and arguments.

For example, suppose the function sum is defined in Stitch as follows:

exports = function(a, b) {
   return a + b;
};

It can be called from the client as follows:

stitchClient.executeFunction("sum", 3, 4).then( /* ... */ );

To execute a function, use the StitchClient.executeFunction() method.

For example, suppose the function sum is defined in Stitch as follows:

exports = function(a, b) { return a + b; };

It can be called from the client as follows:

stitchClient.executeFunction("sum", 3, 4).addOnCompleteListener( /* ... */ );

To execute a function, use the StitchClient.executeFunction() method, passing the function name and arguments.

For example, suppose the function sum is defined in Stitch as follows:

exports = function(a, b) { return a + b; };

It can be called from the client as follows:

stitchClient.executeFunction("sum", args: 3, 4).then( /* ... */ );

Examples

Returning Documents

A very simple function is one which returns an array of documents.

exports = function(arg) {
    return [
       { "type": "apples", "qty": 25 },
       { "type": "oranges", "qty": 50 }
    ];
};

The above function returns the following to the client:

[
  {
    "type": "apples",
    "qty": {
      "$numberLong": "25"
    }
  },
  {
    "type": "oranges",
    "qty": {
      "$numberLong": "50"
    }
  }
]

MongoDB

In order to use MongoDB in a function, you must have rules set up for each namespace included in the operation.

The following example uses a collection called cars in a database called vehicles, with the following documents:

{ "_id": 1, "make": "Honda", "model": "Accord", "doors": 4 }
{ "_id": 2, "make": "Ford", "model": "Mustang", "doors": 2 }
{ "_id": 3, "make": "Toyota", "model": "Camry", "doors": 4 }

The following function finds 2-door cars, and returns only the make and model fields.

exports = function() {
    var mongodb = context.services.get("mongodb-atlas");
    var coll = mongodb.db("vehicles").collection("cars");
    return coll.find({"doors": 2}, { "make": 1, "model": 1}).toArray();
};

The above function returns the following array to the client:

[
  {
    "make": "Ford",
    "model": "Mustang"
  }
]

S3 Service

One use case for a MongoDB Stitch application is to allow users to upload binary data to an Amazon S3 bucket. You can accomplish this in a function using the S3 service.

The following example takes a hex-encoded bytes and uses the put function to upload it to an S3 bucket using an S3 service named “my-s3-service”.

exports = function() {
    var s3 = context.services.get("my-s3-service");
    var binary = BSON.Binary.fromHex("68656c6c6f", 0);
    return s3.put({
       "body": binary,
       "contentType": "text/plain",
       "acl": "public-read",
       "bucket": "my-bucket-name",
       "key": "test-object"
    })
};

Note

In the above example, the key argument to the S3 service represents the path to the object in the S3 bucket, relative to server root. It must not begin with /.

The Twilio Service

The following example uses a MongoDB database called people and a collection called users with the following documents:

{ "_id" : 1, "name" : "Amos", "city" : "Boston", "phone" : "+15558907614" }
{ "_id" : 2, "name" : "Barbara", "city" : "Atlanta", "phone" : "+15558340186" }
{ "_id" : 3, "name" : "Chet", "city" : "Boston", "phone" : "+15553528799" }

The following function combines a find call to a MongoDB service with a send call to a Twilio service named “my-twilio-service”. It sends a text message to all the users who meet the specified criteria.

exports = function() {
    var mongodb = context.services.get("mongodb-atlas");
    var coll = mongodb.db("people").collection("users");
    var twilio = context.services.get("my-twilio-service");
    var docs = coll.find({"city": "Boston"}, {});
    docs.forEach(function(document){
        twilio.send({
            to: document.phone,
            from: context.values.get("twilioNumber"),
            body: "Looks like rain today. Bring an umbrella!"
        });
    });
};

The two users from Boston receive a text message via Twilio. A successful function response returns an empty array to the client.