Event Handlers
Event Handlers
lac31
You can do additional processing and customization using event handlers. Request and response events are JavaScript entry points to perform user-defined actions.
You can create the following types of event handlers:
- Request events.API Creator calls these for every request, after it receives the request but before it begins work.
- Response events.API Creator calls these for every request, before it sends back the (successful) final result to the client.
There is no limit to the number of event handlers you can create.
In this article:
2
Create an Event Handler
- With your API open, in the Manage section, clickRequest Events.If you do not see this option, clear theShort Menucheckbox that appears below the menus.
- ClickAdd.
- Complete the following fields on the page, and then save your changes:Event typeThe type of event.Options:Request event or Response eventEvent Handler nameThe name for your event handler. API Creator invokes request and response events in alphabetical order based on their name.You can have API Creator invoke your request and response events in a specific order by appending the event handler name with a number sequence.CodeThe handler operations for this event handler. For example:if (“default/b2bderbypavlov/v1/SalesResports” == req.resourceName) { //log.debug(‘***SalesReports Req Event - json: ' + json); var data = JSON.parse(json); // json from the request var theOrder = data[0]; var keptItemNum = 0; var keptItems = []; log.debug(“theOrder: " + JSON.stringify(theOrder)); for ( var i = 0; i < theOrder.Order_DetailsList.length; i ++) { var eachItem = theOrder.Order_DetailsList(i); delete eachItem[“@metadata”]; if (eachItem.SupplierName == “Pavlova, Ltd.”) { delete eachItem.OrderID; delete eachItem.ProductID;...ActiveIndicates that this event handler is active. Select this checkbox.
The event handler is created.
How API Creator Invokes Request Event Handlers
API Creator invokes request event handlers using the following process:
- API Creator performs initial authentication.
- API Creator invokes the request event handler for every transaction, with the following variables pre-defined:Variable NameDescriptionjsonThe raw JSON string that the client sends, if any. Set only for POST and PUT requests. You can modify this string.reqThe request object.logThe logger for the current request.API Creator invokes request events in alphabetical order based on their name.You can have API Creator invoke your request events in a specific order by appending the event handler name with a number sequence.
- API Creator establishes a connection to the database.
- API Creator parses the JSON payload.
For more information about how API Creator processes update requests, including how rules integrate with request events, see Logic Execution.
Request Examples
The following example rejects all requests on SecretData if they do not use HTTPS:
// Reject all requests on SecretData if they do not use HTTPSif ("SecretData" == req.resourceName && !req.clientUsesHttps) { log.error('SecretData was accessed over HTTP by ' + req.clientAddress); throw "Use HTTPS to access this resource";}
The following example removes extraneous data that the client sends but that is not needed:
// Remove extraneous data that the client sends but that is not needed.if ( ! json) { // Only requests with a JSON payload are needed. 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: Serialize the data back to a string if you want to change itjson = JSON.stringify(data);
How API Creator Invokes Response Event Handlers
API Creator invokes response event handlers with the following variables pre-defined:
Variable name | Description |
| 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. The
object 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 , , elements. It might also be an error result. The method must be able to stringify the JSON object. |
req | The request object. |
log | The logger for the request. |
getResource | The method that returns a JSON array containing the results of a GET of the named resource. This method has the following syntax:
For more information about the getResource method, see The SysUtility Object. |
API Creator invokes response events in alphabetical order based on their name.
You can have API Creator invoke your response events in a specific order by appending the event handler name with a number sequence.
Response Examples
A fully worked example (provided in the LogicSample 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.
- About the LogicSample database, see Logic Sample Database.
You can also review the following smaller examples:
// 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.// This only deals with top-level resources. To remove all// @metadata sections from a complex resource, 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).// You CAN convert from the Java string value to a JavaScript string object herevar 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];// You 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());}
In the following code snippet, add the top 30 (by
)amount_total
where the employee is the sales rep by augmenting each employee in a GET of multiple employees:purchaseorders
// for a GET to an employee, add any PURCHASEORDERS where the employee is a sales repif ("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; }}
In the following code snippet, include the results of a resource GET by amending the transaction summary:
// for a PUT (perhaps to update the name) of one or more employees// add the picture into the resultif ("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; } } }}
Combine these two examples and delete the usual transaction-summary, redirecting it to be the
getResource
method result. Advanced Usage
Modify the JSON Response
You have full control over the result and can do pretty much anything. The following is an example:
- Create a newMyResourceJavaScript resource defined as:return { Happy: ['New', 'Year']};
- In the REST Lab, view the result by performing a GET request, which is a different formatting of the previous JSON. Complete the following:
- Make sure you 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 = ["I got what I expected"];}else { // this is returned on ALL other requests, make sure you delete this !!! json = ["Not what I wanted"];}
- Change to a more specific handler without the else condition:// Note double equals, as you are comparing JavaScript strings with java.lang.String objectsif ('GET' == req.verb.name && 'MyResource' == req.resourceName) { json = getResource('demo:customer');}
The handler takes a value from the request and creates a new customer.
- About transaction summaries, see Transaction Summary.
- About viewing an advanced example of using event handlers, see Integrate Systems and Data.
- About therequestobject, see The Request Object.