Server Method Invocation

The Server Method Invocation (SMI) feature enables you to build an app with a front-end component that can invoke a serverless component. To do this:

  1. In the manifest.json > functions object, specify all the server methods that are called from the front-end component of the app, to allowlist the methods.

  2. In the front-end component (app.js), specify the method to invoke the serverless component and pass an appropriate payload to the serverless component. By default, the serverless environment adds the installation parameters set during app installation to the payload.

  3. In the serverless component (server.js), define the server method (SMI function) that is allow-listed in the app manifest and called from the front-end component. In this server method, include the app logic that runs based on the payload passed and the renderData() method to return success and failure responses to the front-end component.

A few use cases for this feature are listed below.

  1. You can use node libraries to simplify app development.
  2. You can hide sensitive information, such as static API keys or other configuration settings, from end users.

Notes:
  1. The rate limit for the serverless component is 50 triggers per minute.
  2. The serverless component’s app execution timeout is five seconds.
  3. The payload passed to the severless component should not exceed 100KB.

Take a look at the Twilio Freshdesk sample app for a demonstration of this feature. The same functionality is available in Freshteam.

Register the SMI function

  1. From the app’s root directory, navigate to manifest.json.

  2. In the product.<productName> attribute, include the functions object as follows, to allow list the SMI functions that are defined in server.js:

    Note: If the front-end component tries to invoke a function/method that is not registered in the app manifest, the fdk run or fdk validate commands display the error message Requested function not found or registered.


  3. Copied Copy
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    { "platform-version": "2.2", "product": { "freshteam": { "location": { "candidate_sidebar": { "url": "index.html", "icon": "styles/images/icon.svg" } }, "events": { "onApplicantCreate": { "handler": "onApplicantCreateCallback" }, "OnApplicantUpdate": { "handler": "OnApplicantUpdateCallback" } }, "functions": { "serverMethod1": { "timeout": 10 }, "serverMethod2": { "timeout": 15 } } } }, "whitelisted-domains": [ "https://www.google.com" ] }
    EXPAND ↓
  4. For the functions.<serverMethodName>.timeout attribute, specify a function-based app execution timeout value in seconds. The valid values for timeout are 5, 10, 15, and 20.

    Notes:
    • If the SMI function does not return a response within the stipulated time, the app execution times out and an error message is displayed.
    • If an invalid timeout value is specified, the fdk run or fdk validate commands display the error message Timeout should be one of the allowed values.

Invoke the Serverless Component

  1. From the app’s root directory, navigate to the app.js file.
  2. Define the JSON payload that is to be passed to the method in the server.js file. In the following sample app.js code, options is the JSON payload that is passed.
  3. Include the client.request.invoke(“serverMethodName”, JSON_payload) method to invoke the serverless component. By default, the serverless environment adds an iparams object to the payload.
  4. Include functions to handle the response obtained from the serverless component.

Sample app.js code Copied Copy
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
var options = { "url": "https://api.github.com/users/sample" }; client.request.invoke("serverMethod", options).then( function(data) { // data is a json object with requestID and response. // The serverless environment generates the request ID. // The serverless method in server.js returns two objects (error,response). // data.response is the response object from the serverless method. console.log("Server method Request ID is: " + data.requestID); console.log("Server method response is: " + data.response); }, function(err) { // err is a json object with requestID, status, and message. // The serverless environment generates the request ID. // The serverless method in server.js returns two objects (error,response). // The error object contains the status and message attributes. // err.status is the error.status attribute. // err.message is the error.message attribute. console.log("Request ID: " + err.requestID); console.log("error status: " + err.status); console.log("error message: " + err.message); });
EXPAND ↓
Sample JSON_payload Copied Copy
1
2
3
4
5
6
7
{ "url": "https://api.github.com/users/sample", "iparams": { "<iparam1>": "<value1>", "<iparam2>": "<value2>" } }
Send Response to the Front-end Component

After the app logic in the server method runs, the server method sends an appropriate response to the front-end component. To enable this:

  1. Navigate to the server.js file. Define the server method (SMI function) that is called from the front-end component. Place the app logic inside the server method.
    Notes:
    • The SMI function name is case-sensitive.
    • The SMI function name:
      • Can be alphanumeric ([a-z], [A-Z], [0-9]) and can contain the special character underscore ( _ ).
      • Should not start with a number.
      • Should not contain any spaces between the characters.
      • Can be 2 to 40 characters long.
    • If an SMI function registered in the app manifest, is not defined in server.js, the fdk run and fdk validate commands display the error message Function <function-name> not defined for the product <product-name>.

  2. Navigate to the server.js file. In the exports code block, define the server method that is called from the front-end component. Place the app logic inside the server method.

  3. Use the renderData(error, data) method to return a response to the front-end component.
    Notes:
    • error and data are passed as JSON objects to the caller method. Ensure that the first argument of renderData(error, data) is always the error object. For success responses, ensure to pass null as the first argument.
    • error is an object with status and message attributes. data is an object with valid <key>: <value> pairs.
    • The serverless environment adds a requestID attribute, to the error or data object.

  4. To send a success response, use the renderData() method as follows: Copied Copy
    1
    2
    3
    4
    5
    6
    exports = { serverMethod: function(options) { // app logic resides here renderData(null, { "key": "value" }); } }
    The front-end component can render the success response as follows: Copied Copy
    1
    2
    3
    4
    { requestID: "2edc13f8-3b81-4ade-b857-8d8e316fa87c", response: { "key": "value" } }
  5. To send a failure response, use the renderData() method as follows: Copied Copy
    1
    2
    3
    4
    5
    6
    exports = { serverMethod: function(options) { var error = { status: 403, message: "Error while processing the request" }; renderData(error); } }
    The front-end component can render the failure response as follows: Copied Copy
    1
    2
    3
    4
    5
    { "requestID": "2edc13f8-3b81-4ade-b857-8d8e316fa87c", "status": 403, "message": "Error while processing the request" }
    If error.statusis not present, the default status code of 500 is used as the error status. If the error object in renderData(error) is of incorrect JSON format, error.status value is 400 and error.message value is “The error should be a JSON Object with a message or a status parameter.” The front-end component can render this error as follows: Copied Copy
    1
    2
    3
    4
    5
    { "requestID": "2edc13f8-3b81-4ade-b857-8d8e316fa87c", "status": 400, "message": "The error should be a JSON Object with a message or a status parameter." }
Note: If the server method does not return a response, the app execution timeout error occurs.
Testing

For information on how to test an app that uses the SMI feature, see Test the App.