Docs‎ > ‎Reference‎ > ‎

Request Events

API Creator project can have any number of event handlers, which will be automatically executed at certain points during a request.
There are currently two types of event handlers:
  • request event handlers are called for every request, right after the request has been received, but before any "serious" work has really begun.
  • response event handlers are called for every request, right before the final result is sent back to the client (assuming the request was successful).

Event handlers can be used to do some additional processing and customization. They are created using the Logic Designer, like this:


Request events

A request event handler is invoked for every transaction, once the initial authentication has been performed. No connection to the database has yet been established, and the JSON payload (in the case of POST and PUT) has not yet been parsed.

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

 Variable name Description
 json The raw JSON string sent by the client, if any. This will be set only for POST and PUT requests, since GET and DELETE do not have a JSON payload. You can (carefully) modify this if needed.
 req The request object
 log The logger for the current request.

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 will be 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 will be a single object or an array of objects depending on the details of the request.  For PUT/POST/DELETE this will be 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 Logic Sample) illustrates preparing a partner-specific response by materializing a Resource, and returning it as the response message.  They key pattern is that Resource Object / Attribute aliases are defined to match partner expectations.

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, we augment each employee in a GET of multiple employees, to add the top 30 (by amount_total) purchaseorders where
the employee is the sales rep.

// 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, we amend the usual transaction-summary response to include the results of a Resource GET. 

// 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.

Create a new JavaScript resource named MyResource defined simply as

return { Happy: ['New', 'Year']};

In the REST Lab, perform a GET request to see the result, which will be a slightly different formatting of the above JSON.

Define a simple RESPONSE event just to make sure we are at least functioning a bit.  Note that 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 will be 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 will be returned on ALL other requests, make sure you delete this !!!
    json = ["Not what we wanted"];
}

After verifying that the RESPONSE event is executing and we understand the simple example above, we will 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');
}