Todd Appleton - September 4, 2014

ToddAppleton

A while back we introduced event scripts to the DreamFactory Services Platform (DSP). These scripts are triggered by events on specific resources such as a GET on a database table.  Starting with version 1.7.8 DreamFactory supports a second type of script called custom script.  Custom scripts are a little more flexible than event scripts because you can write custom scripts to implement any functionality you want and the client can invoke them directly via the REST API.  

They can make calls to your DSP’s services and perform any required business logic before returning the final result back to the client.  To get this functionality you’ll need a non-hosted DSP, which means installing DreamFactory on your local machine using Bitnami installers or spinning up a VM in the cloud. You can check out our wiki for information on how to get started with DreamFactory.

Let’s jump right in and show how to create a new custom script. Our goal is to create a simple script named ‘add’ that adds two numbers. We want to invoke the script from the REST API by passing the two numbers to add as query parameters.

POST /rest/system/script/add?is_user_script=true&n1=4&n2=2

In the URL ‘add’ is the id/name of the script. The script will read the numbers n1 and n2 and return their sum. is_user_script should always be set to true when calling custom scripts.

The first step to implement this script is to go to the admin console and create the new script. Click Scripts in the list on the left. This takes you to the scripts editor where you can select either Event Scripts or Custom Scripts.

custom_script_1

 Click Custom Scripts then click ‘Create New Script’.

custom_script_2

Enter an id/name of ‘add’. Do not add a .js extension to the name. The right panel is a text editor for editing your scripts.  Enter the following Javascript there and click Save.

var result = Number(event.n1) + Number(event.n2);
return result;

Now the script is available from the REST API. As you can see the script simply adds the two numbers and returns the result. At runtime every script has access to an object named ‘event’ that contains contextual information about the API request that triggered the script to run. All query parameters from the POST request will be included as fields in the event object. For this example there are two query params n1 and n2.  A sample event for this script is shown below.

{
    "is_user_script": "true",
    "n1": "4",
    "n2": "2",
    "path": "system/script/add",
    "__tag__": "exposed_event"
}

The response returned to the client will look much the same but will also include a script_result field set to the script’s return value. This could be a number, a string, an array of records, or whatever you like. For our example it’s just a number, the sum of n1 and n2.

{
    "is_user_script": "true",
    "n1": "4",
    "n2": "2",
    "path": "system/script/add",
    "__tag__": "exposed_event",
    "script_result": 6
}

Scripts can also write to the DSP’s log file which is useful for debugging. The PHP functions print, print_r, and var_dump are available to be called from the Javascript engine. By default the output of these will go to the log file in your DSP’s /log directory. On a Bitnami OS X installation that directory would be something like

/Applications/dreamfactory-1.7.8-0/apps/dreamfactory/htdocs/log

Adding the following line to the script would write to your log file. Please use logging sparingly as it does negatively affect script performance.

print(event.n1 + " + " + event.n2 + " = " + result);

The output would look like this.

[2014-09-03 16:37:53] app.INFO: Script User Script "add" output:
4 + 2 = 6
 [] []

When the client receives the response to its POST request it can easily access the script’s return value as response.script_result. Scripts can also throw exceptions, which results in a 500 error being sent back to the client.

Hopefully this has given you some ideas on getting started with custom scripting. If you have any questions about scripting or DSP in general please visit our wiki, our forums, or contact support directly.