Navigation

Functions

➤ Functions are written in Javascript.
➤ Functions are written in the function editor and referenced by name.

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

Note

Function assignments must be to the global exports object.

const exports = function(arg) { ... } // Invalid variable declaration
exports = function(arg) { ... }     // Valid function

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:

yourStitchClient.executeFunction("increment", 1).then(/* ... */);
yourStitchClient.executeFunction("increment", 1).addOnCompleteListener(/* ... */);
yourStitchClient.executeFunction(name: "increment", args: 1).done { (response: Any) in
   /* ... */
}
➤ 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) {
  const mongodb = context.services.get("mongodb-atlas");
  const coll = mongodb.db("db").collection("users");
  const twilio = context.services.get("my-twilio-service");
  const yourTwilioNumber = context.values.get("twilioNumber");

  coll.find().toArray().then(users => {
    users.forEach(user => twilio.send({
        to: user.phone,
        from: yourTwilioNumber,
        body: message
      });
    );
  });
};

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

➤ Functions have access to various utility functions for developer convenience.
  • console can be used to output to the debug console and console logs.
  • JSON can be used to convert between string and object representations of standard JSON.
  • EJSON can be used to convert between string and object representations of MongoDB Extended JSON.
  • BSON can be used to construct and manipulate BSON types.
  • utils.crypto provides a method for creating HMAC signatures, which is useful when your functions communicate with external HTTP services.

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.

Function Utilities

In addition to the context global variable, the following variables which provide utility functions are also available:

Variable Description
console Access to functions that can output to the debug console and console logs.
JSON Access to functions to convert between string and object representations of standard JSON. This is a standard built-in object across most Javascript environments and is documented here.
EJSON Access to functions to convert between string and object representations of MongoDB Extended JSON.
BSON Access to functions to construct and manipulate BSON types.
utils.crypto Access to a method for creating HMAC signatures, which is useful when your functions communicate with external HTTP services.

For more information, see Function Utilities.

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.

yourStitchClient.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.

Service Description Basic Example
MongoDB Atlas Interact with a MongoDB database.
exports = function() {
    const mongodb = context.services.get("mongodb-atlas");
    const coll = mongodb.db("db").collection("coll");
    return coll.findOne({});
};
Amazon S3 Store data.
exports = function() {
    const 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() {
    const 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() {
    const http = context.services.get("my-http-service");
    return http.get({url: "http://google.com"});
};
Twilio Send and receive text messages.
exports = function() {
    const 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:

yourStitchClient.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:

yourStitchClient.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:

yourStitchClient.executeFunction("sum", args: 3, 4).done{ (response: Any) in
    /* ... */
}

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() {
  const mongodb = context.services.get("mongodb-atlas");
  const coll = mongodb.db("vehicles").collection("cars");
  return coll
    .find({"doors": 2}, { "make": 1, "model": 1})
    .toArray()
};

The above function returns a promise to the client that resolves to the following array:

[
  {
    "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() {
    const s3 = context.services.get("my-s3-service");
    const 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() {
  const mongodb = context.services.get("mongodb-atlas");
  const users = mongodb.db("people").collection("users");
  const twilio = context.services.get("my-twilio-service");
  users
    .find({"city": "Boston"})
    .toArray()
    .then(docs => {
      docs.forEach(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.