# Modifying Existing API Endpoint Logic

The scripting interface is accessible via the Scripts tab located at the top of the DreamFactory administration console. Once entered, you'll be presented with a list of APIs hosted within your DreamFactory instance. Enter one of the APIs and you'll see a top-level summary of the endpoint branches associated with that API. For instance, if you enter a database-backed API you'll see branches such as _func (stored function), _proc (stored procedure), _schema (table structure), and _table (tables). For instance, this screenshot presents the top-level interface for a Microsoft SQL Server API:

If you keep drilling down into the branch, you'll find you can apply logic to a very specific endpoint. Additionally, you can choose to selectively apply logic to the request (pre-process) or response (post-process) side of the API workflow, can queue logic for execution outside of the workflow, and can specify that the logic executes in conjunction with a specific HTTP verb (GET, POST, etc.). We'll talk more about these key capabilities later in the chapter.

If you continue drilling down to a specific endpoint, you'll eventually arrive at the script editing interface. For instance in the following screenshot we've navigated to a SQL Server API's customer table endpoint. Specifically, this script will execute only when a GET request is made to this endpoint, and will fire after the data has been returned from the data source.

TIP

DreamFactory's ability to display a comprehensive list of API endpoints is contingent upon availability of corresponding OpenAPI documentation. This documentation is automatically generated for the native connectors, however for connectors such as Remote HTTP and Scripted, you can supply the OpenAPI documentation in order to peruse the endpoints via the scripting interface. One great solution for generating OpenAPI documentation is Stoplight.io.

Although the basic script editor is fine for simple scripts, you'll probably want to manage more complicated scripts using source control. After configuring a source control API using one of the native Source Control connectors (GitHub, BitBucket, and GitLab are all supported), you'll be able to link to a script by selecting the desired API via the Link to a service select box located at the bottom left of the interface presented in the above screenshot.

# Examples

Let's review a few scripting examples to get your mind racing regarding what's possible.

# Validating Input Parameters

When inserting a new record into a database you'll naturally want to first validate the input parameters. To do so you'll add a pre_process event handler to the target table's post method endpoint. For instance, if the API namespace was mysql, and the target table was employees, you would add the scripting logic to the mysql._table.account.post.pre_process endpoint. Here's a PHP-based example that examines the POST payload for missing values and also confirms that a salary-related parameter is greater than zero:

$payload = $event['request']['payload'];

if(!empty($payload['resource'])){
    foreach($payload['resource'] as $record){
        if(!array_key_exists('first_name', $record)){
            throw new \Exception('Missing first_name.');
        }

        if(!array_key_exists('hire_date', $record)){
            throw new \Exception('Missing hire_date.');
        }

        if($record['salary'] <= 0){
            throw new \Exception('Annual salary must be > 0');
        }
    }
}

# Transforming a Response

Suppose the API data source returns a response which is not compatible with the destination client. Perhaps the client expects response parameters to be named differently, or maybe some additional nesting should occur. To do so, you can add business logic to a post_process endpoint. For instance, to modify the response being returned from the sample MySQL database API's employees table endpoint, you'll add a script to mysql._table.employees.get.post_process. As an example, here's what a record from the default response looks like:

{
    "emp_no": 10001,
    "birth_date": "1953-09-02",
    "first_name": "Georgi",
    "last_name": "Facello",
    "gender": "M",
    "hire_date": "1986-06-26"
}

Suppose you instead want it to look like this:

{
    "emp_no": 10001,
    "birth_date": "1953-09-02",
    "name": "Georgi Facello",
    "gender": "M"
}

Specifically, we've combined the first_name and last_name parameters, and removed the hire_date parameter. To accomplish this you can add the following PHP script to the mysql._table.employees.get.post_process endpoint:

$responseBody = $event['response']['content'];

foreach ($responseBody['resource'] as $n => $record) {
    $record["name"] = $record["first_name"] . " " . $record["last_name"];
    unset($record["first_name"]);
    unset($record["last_name"]);
    unset($record["hire_date"]);
    $responseBody['resource'][$n] = $record;
}

$event['response']['content'] = $responseBody;