Scripting
DreamFactory supports server-side scripting to quickly and easily customize almost all of the platform's REST API endpoints to include business logic on the server, such as field validation, workflow triggers, runtime calculations, and more. Developers can easily attach scripts to any existing API endpoint, for both pre- and post- processing of the request and response. You can also write your own custom REST APIs with server-side scripts.
Contents
Supported Scripting Languages
Where Scripts Can Be Used
Resources Available To A Script
When a script is executed, DreamFactory passes in two very useful resources that allow each script to access many parts of the system including system states, configuration, and even a means to call other services or external APIs. They are the event resource and the platform resource.
Note: The term "resource" is used generically here, based on the scripting language used, the resource could either be an object (i.e. V8js or Node.js) or an array (i.e. PHP).
The Event Resource
The event resource contains the structured data about the event triggered (System Events Scripting) or from the API service call (Custom Scripted Services). As seen below, this includes things like the request and response information available to this "event".
Note: Determined by the type of event triggering the script, parts of this event resource are writable. Modifications to this resource while executing the script will result in a change to that resource (i.e. request or response) in further internal handling of the API call.
The event resource has the following properties:
Property | Type | Description |
---|---|---|
request | resource | A resource representing the inbound REST API call, i.e. the HTTP request. |
response | resource | A resource representing the response to an inbound REST API call, i.e. the HTTP response. |
resource | string | Any additional resource names typically represented as a replaceable part of the path, i.e. "table name" on a db/_table/{table_name} call. |
Event Request
The "request" resource contains all the components of the original HTTP request. This resource is always available, and is writable during pre-process event scripting.
Property | Type | Description |
---|---|---|
api_version | string | The API version used for the request (i.e. 2.0). |
method | string | The HTTP method of the request (i.e. GET, POST, PUT). |
parameters | resource | An object/array of query string parameters received with the request, indexed by the parameter name. |
headers | resource | An object/array of HTTP headers from the request, indexed by the lowercase header name. |
content | string | The body of the request in raw string format. |
content_type | string | The format type (i.e. "application/json") of the raw content of the request. |
payload | resource | The body (POST body) of the request, i.e. the content, converted to an internally usable object/array if possible. |
content_changed | boolean | Set this to true to copy the content back into the event handling stream on pre-process scripts. |
Any changes to this data will overwrite existing data in the request, before further listeners are called and/or the request completes.
Event Response
The response resource contains the data being sent back to the client from the request.
Note: This resource is only available/relevant on post-process event scripts, and Custom Scripting service scripts.
Property | Type | Description |
---|---|---|
status_code | integer | The HTTP status code of the response (i.e. 200, 404, 500, etc). |
headers | resource | An object/array of HTTP headers for the response back to the client. |
content | mixed | The body of the request as an object if the content_type is not set, or in raw string format. |
content_type | string | The content type (i.e. json) of the raw content of the request. |
content_changed | boolean | Set this to true to copy the content back into the event handling stream on post-process scripts. |
Just like request, any changes to response will overwrite existing data in the response, before it is sent back to the client ONLY if you set the content_changed flag to true.
The Platform Resource
This platform resource may be used to access configuration and system states, as well as, the REST API of your instance via inline calls. This makes internal requests to other services directly without requiring an HTTP call.
The platform resource has the following properties:
Field | Type | Description |
---|---|---|
api | resource | An array/object that allows access to the instance's REST API. |
config | resource | An array/object consisting of the current configuration of the instance. |
session | resource | An array/object consisting of the current session information. |
Platform API
The api resource contains methods for instance API access. This object contains a method for each type of REST verb.
Function | Description |
---|---|
get | GET a resource |
post | POST a resource |
put | PUT a resource |
patch | PATCH a resource |
delete | DELETE a resource |
They all accept the same arguments:
method( "service[/resource_path]"[, payload[, curl_options]] );
- method - Required. The method/verb listed above.
- service - Required. The service name (as used in API calls) or external URI.
- resource_path - Optional depending on your call. Resources of the service called.
- payload - Optional, but must contain a valid object for the language of the script.
- curl_options - Optional for external calls only.
Calling internally only requires the relative URL sans the /api/v2/ portion:
// Retrieve all records from the 'Contacts' table in the 'db' database service platform.api.get( "db/_table/Contacts" );
You may also pass absolute URLs to these methods to retrieve external resources:
platform.api.get( "http://www.google.com" );
or
platform.api.post( "https://www.example.com/api/something_cool", {"cool":"very"} );
Adding headers or other cURL options to api calls
For example to add headers
var options = { "CURLOPT_HTTPHEADER": ["Content-type: application/json", "Some-Other-Header: blah"] }; result = platform.api.post("http://example.com/my_api", {"name":"test"}, options);
Note: The double quotation marks around the CURLOPT_* constant names are required in Javascript, unlike PHP.
You can also add multiple cURL options like this.
var options = { "CURLOPT_HTTPHEADER": ["Content-type: application/json", "Some-Other-Header: blah"], "CURLOPT_SOMEOTHEROPTION": "someothervalue" }; result = platform.api.post("http://example.com/my_api", null, options);
Platform Config
The config object contains configuration settings for the instance.
Function | Description |
---|---|
df | Configuration settings specific to DreamFactory.
( [version] => "2.1.0" [api_version] => "2.0" [always_wrap_resources] => true [resources_wrapper] => "resource" [storage_path] => "my/install/path/storage" ... ) |
Platform Session
The session resource contains information and states about the current session for the event.
Function | Description |
---|---|
api_key | DreamFactory API key. |
session_token | Session token, i.e. JWT. |
user | User information derived from the supplied session token, i.e. JWT.
( [id] => 6 [display_name] => First Last [first_name] => First [last_name] => Last [email] => [email protected] [is_sys_admin] => 1 [last_login_date] => 2016-02-19 14:05:25 ) |
app | App information derived from the supplied API key. |
lookup | Available lookups for the session. |
Stopping Script Execution
Just like in normal code execution, execution of a script is stopped prematurely by two means, throwing an exception, or returning.
// Stop execution if verbs other than GET are used in Custom Scripting Service if (event.request.method !== "GET") { throw "Only HTTP GET is allowed on this endpoint."; // will result in a 500 back to client with the given message. } // Stop execution and return a specific status code if (event.resource !== "test") { event.response.status_code = 400; event.response.content = {"error": "Invalid resource requested."}; return; } // defaults to 200 status code event.response.content = {"test": "value"};
Halting Event Propagation
Event scripts can halt propagation to future listeners as well. Setting the event.stop_propagation property to true will halt propagation of the event immediately upon return from the script.