Docs‎ > ‎Quick Reference‎ > ‎

Request Events

API Creator can have any number of event handlers, which are automatically executed at certain points during a request. The following types of event handlers are included:
  • Request event handlers. API Creator calls these for every request, after it receives the request but before it begins any "serious" work.
  • Response event handlers. API Creator calls these for every request, before it sends back the (successful) final result to the client.
You can do some additional processing and customization using event handlers.

Create Event Handlers

Create event handlers using the logic designer, as shown in the following image:

Request Event Handler

Request event handlers are invoked using the following process:

  1. Initial authentication is performed.
  2. The request event handler is invoked for every transaction, with the following variables pre-defined:
     Variable NameDescription
     jsonThe raw JSON string sent by the client, if any. This is set only for POST and PUT requests, since GET and DELETE do not have a JSON payload. You can (carefully) modify this if needed.
     reqThe request object.
     logThe logger for the current request.
  3. A connection to the database is established.
  4. The JSON payload (for POST and PUT) are parsed.
For more information about request objects, see The Request object.

Request Examples

// Reject all requests on SecretData if they do not use HTTPS
if ("SecretData" == req.resourceName && !req.clientUsesHttps) {
    log.error('SecretData was accessed over HTTP by ' + req.clientAddress);
    throw "This resource must be accessed over HTTPS";
}

// Remove extraneous data that the client sends, but that we don't want.
if ( ! json) {
    // We're only interested in requests with a JSON payload
    return;
}
var data = JSON.parse(json);
if (Array.isArray(data)) {
    for (var i = 0; i < data.length; i++) {
        delete data[i].uselessData;
    }
}
else {
    delete data.uselessData;
}

// Important: you must serialize the data back to a string if you want to change it
json = JSON.stringify(data);

Response Events

Response event handlers are invoked with the following variables pre-defined:

 Variable name Description
 json The complete response object, which is sent back to the client after the response event handlers (if any) have been executed. You can (carefully) change OR replace this object.
Note that this is different from request events: this is not a string, but rather an object or an array of objects. For a GET, this is a single object or an array of objects depending on the details of the request. For PUT/POST/DELETE this is a single object with statusCode, txsummary, rulesummary elements. It may also be an error result. It MUST be able to be stringify'd by JSON.stringify().
 req The request object
 log The logger for the request.
 getResource Function that returns a JSON array containing the results of a GET of the named resource.

Response Examples

A fully worked example (provided in the Logic Sample database) illustrates preparing a partner-specific response by materializing a resource and returning it as the response message. The key pattern is that resource object/attribute aliases are defined to match partner expectations.

For more information about resource object/attribute aliases matching partner expectations, see Logic Patterns.

You can also review the smaller examples below:
// Remove all @metadata sections from the response for a specific table/resource
// Note: this would make it difficult for the client to update the data, but this is only an example.
// Also note that this only deals with top-level resources. If you wanted to remove all
// @metadata sections from a complex resource, you'd probably need to use recursion.

// An attribute 'TheVerb' is added to each array object or the single object
// with the name of request verb - GET, PUT, POST, PATCH, DELETE

// get the name used for metadata (configurable by project).
// we CAN convert from the Java string value to a JavaScript string object here
var metadataName = new String(req.metadata_name);

if (Array.isArray(json)) {
    // If the response is an array of objects
    for (var i = 0; i < json.length; i += 1) {
        delete json[i][metadataName];

        // we MUST convert to native JavaScript string
        json[i]['TheVerb'] = new String(req.verb.name());
    }
}
else {
    // The response is a single object
    delete json[metadataName];
    json['TheVerb'] = new String(req.verb.name());
}

Here, add the top 30 (by amount_total) purchaseorders where the employee is the sales rep by augmenting each employee in a GET of multiple employees:

// for a GET to an employee, add any PURCHASEORDERS where the employee is a sales rep
if ("GET" == req.verb && "employee" == req.resourceName && json.length) {
    for (var i = 0;  i < json.length; i += 1) {
        // want purchase orders for this employee as sales rep
        // top thirty purchase orders by amount_total
        var detail = {
            filter: "salesrep_id = " + json[i].employee_id,
            order: "amount_total desc",
            pagesize: 30,
            offset: 0,
            verbose: false
        };
        var ordersAsSalesRep = getResource("purchaseorders", detail);
        json[i].ordersAsSalesRep = ordersAsSalesRep;
    }
}

Here, include the results of a Resource GET by amending the usual transaction-summary response:

// for a PUT (perhaps to update the name) of one or more employees
// add the picture into the result
if ("PUT" == req.verb && "employee" == req.resourceName) {
    var txsummary = json.txsummary;
    for (var i = 0, len = txsummary.length;  i < len;  i += 1) {
        var meta = txsummary[i]["@metadata"];
        if ("UPDATE" == meta.verb && "employee" == meta.resource) {
            var detail = { filter: "employee_id = " + summary[i].employee_id  };
            var picInfo = getResource("employee_picture", detail);
            if (picInfo && picInfo.length > 0) {
               txsummary[i].the_picture = picInfo[0].picture;
            }
        }
    }
}

Or, you might want to combine these two examples, and delete the usual transaction-summary, "redirecting" it to be the getResource result.

Advanced Usage

You have full control over the result and can do pretty much anything.
  1. Create a new JavaScript resource named MyResource defined as:
    return { Happy: ['New', 'Year']};
  2. In the REST Lab, view the result by performing a GET request, which is a different formatting of the previous JSON.
  3. Make sure we are at least functioning by defining a simple RESPONSE event. If the RESPONSE event appears to be non-functional, check that it is configured as a RESPONSE event and not as a REQUEST event:
    // MUST be an object or an array, if not, it is coerced into one (and probably NOT what you want)
    if ('GET' == req.verb.name() && 'MyResource' == req.resourceName) {
        json = ["We got what we expected"];
    }
    else {
        // this is returned on ALL other requests, make sure you delete this !!!
        json = ["Not what we wanted"];
    }
  4. Change to a more specific handler without the else condition and that takes a value from the request and creates a new customer:
    // note double equals, as we are comparing JavaScript strings with java.lang.String objects
    if ('GET' == req.verb.name() && 'MyResource' == req.resourceName) {
        json = getResource('demo:customer');
    }