<< Click to Display Table of Contents >> API for connectors |
When creating your own Bizagi connectors, and specifically a custom connector, you will need to write your own code, as described at Custom connectors.
In order to do this, it is important that you rely on the API provided by Bizagi when applicable.
The starting point when creating your custom Bizagi connector is implementing the invoke function as included by Bizagi when defining a new action:
Note you may include additional functions to help you out organize your code. However, what you need to acknowledge is that the invoke function will always be the starting point when Bizagi runs a connector's given action. |
In this function you may include code as supported by JavaScript and as provided by Bizagi API.
Within the function's input parameters, notice you are provided with the following objects:
OBJECT |
TYPE |
DESCRIPTION AND EXAMPLE |
---|---|---|
globals |
Object |
Contains all parameters as defined within the tabs presented in the rightmost panel: Connector, Authentication and Errors. These parameters are accessed according to the above categories, as: •Connector parameters: globals.systemproperties.[your_parameter] •Authentication parameters: globals.authdata.[your_parameter]
For more information about the global parameters, click here. Additionally, the project's name is available as globals.projectname |
actionName |
String |
Contains the name of the action you are implementing. Though it is not commonly needed, the purpose of this information is for you to use for detailed tracing and logging. |
data |
Object |
Contains all values that make part of the defined inputs and the defined outputs. Access them as: •data.inputs.input.[structure_inside_input] (as defined in your input structure) •data.outputs.output.[structure_inside_output] (as defined in your output structure) or data.outputs.error.[structure_inside_error] |
authenticationType |
Object |
Contains the authentication types supported by your implementation. Though it is not commonly needed, the purpose of this object is for you to check its value to separate the implementation of your action should you need to use more than 1 type of authentication (basic, digest or oauth2). None can be also valid. |
LOG |
Object |
Enables the use of the tracing. It provides a set of functions for you to write into the logged detail in different tracing levels (debug, info, error, warn or trace). For example: LOG.info('detailed_stack'); |
callback |
Function |
Refers to the callback function you need to include to notify Bizagi that your invocation has been completed. It receives mandatory JSON-structured information and its use is typically set as either: •callback(response_information); for a successful invocation •callback(error); should an error occur
For further information about the callback function, click here. |
The API for you to use in custom connectors is provided by the bz-util library which is automatically included in every new connector (these part from already having bizagiUtil as: var bizagiUtil = require ('bz-util'); ).
Methods offered by this API are described in the tables shown below.
METHOD AND INPUTS |
OUTPUT AND DESCRIPTION |
EXAMPLE |
---|---|---|
REQUIRED (string moduleName) |
Imports a node.js library (specified by moduleName). Returns an instance of the object of that imported library. |
The following example, imports a node.js library called twit, into a variable set as TwitterService for further use:
var TwitterService = bizagiUtil.REQUIRED('twit'); |
getResponse (JSON response, JSON error, integer statuscode, string errormsg) |
Allows you to format a successful response to send it back to Bizagi. The successful response is to be set in the response JSON-structured parameter, while exceptions require filling in the JSON-structured parameter called error and a legible string-type error message (given by errormsg). For either successful invocations or those presenting errors, it is recommended to define your own unique status codes (given by statuscode). |
This example considers a successful invocation: var success = bizagiUtil.getResponse({data: {key: ‘s22ssoj44sfj’}}, null, 200, null);
This example considers an error during the invocation: var error = bizagiUtil.getResponse (null, {error: ‘invalid_request’}, 400, ‘The request is missing a required authentication parameter’); |
validator.isValidDataJson (JSON json) |
Validates if a JSON is well formed, i.e compliant to standard JSON for the data parameter. Returns an object having a success element set to true if it is, while returns false if it doesn't, and it also pushes the JSON output or error structure accordingly into data.outputs.output or data.outputs.error.
The exact structure of the returned object is: { response: { outputs: { output: {}, error: {} } }, success: true|false, connectorstatuscode: 200|?, errormessage: "" } |
This example validates the content in globals: var result = bizagiUtil.validator.isValidDataJson(data); if (result.success) { return; |
validator.isValidGlobalsJson (JSON globals) |
Validates if a JSON is well formed, i.e compliant to standard JSON, for the globals parameter. Returns an object having a success element set to true if it is, while returns false if it doesn't, and it also pushes the JSON output or error structure accordingly into response.outputs.error.
The exact structure of the returned object is: { response: { outputs: { output: { globals {...} }, error: {} } }, success: true|false, connectorstatuscode: 200|?, errormessage: "" } |
This example validates the content in globals: var result = bizagiUtil.validator.isValidGlobalsJson(globals); if (result.success) { return; |
error (string errorId, object[] detail) |
Allows you to format an error so that you catch and manage it. Error information gets structured with a main error identifier (errorId) and having further detail such as error code and detailed message. |
This example formats an error message with a status-code 500:
var errormsg = bizagiUtil.error('OBJECT_REF', [500, 'Unsupported parameter value or unknown data']); |
LOG.error (object[] detail) |
Logs the detail provided in the message for error-level tracing. Notice you may concatenate into an array multiple texts. |
The following 2 examples are valid: •LOG.error (['Error 009']); •LOG.error ('[My connector] Error:', error, {'invalid request'} ]); |
LOG.debug (object[] detail) |
Logs the detail provided in the message for debug-level tracing. Notice you may concatenate into an array multiple texts. |
Same use as in LOG.error() |
LOG. warn (object[] detail) |
Logs the detail provided in the message for warning-level tracing. Notice you may concatenate into an array multiple texts. |
Same use as in LOG.error() |
LOG. trace (object[] detail) |
Logs the detail provided in the message for basic tracing. Notice you may concatenate into an array multiple texts. |
Same use as in LOG.error() |
LOG.info (string[] message) |
Logs the detail provided in the message for information-level tracing. Notice you may concatenate into an array multiple texts. |
Same use as in LOG.error() |
Always use those traces and log capabilities offered by Bizagi API, which can be turned off and on by means of settings in Bizagi. Make sure that you define accurately such information (the right amount of tracing, useful and legible information at best, etc), and do not log details into another destination. |
The callback function is in charge of notifying Bizagi when the invocation of an action has finished. Since the communication between the connector framework and the connector itself is asynchronous, this function is used as a communication bridge when the action ends its execution.
The callback function receives as a parameter a response type object, which has the following parameters:
•output: JSON object with the same structure defined in the action's outputs. You have to include this parameter only for successful responses; else, its value is null.
•errorOutput: JSON object with the same structure defined in the action's outputs. You have to include this parameter only for non successful responses, else, its value is null.
•statusCode: code that indicates the status of the response. We recommend that you use the following status code nomenclature for when you code your actions:
oStatus codes from 400 to 500: To declare issues during authentication.
oNegative status codes: To declare exceptions in the logic of your invocation.
o200 status code: Should be specified for a successful invocation.
•errorTitle: message shown when an error occurs. You may use the same value as the one specified in the errorOutput.error. You have to include this parameter only for non successful responses.
Using the Response object in the callback function
The following code illustrates an example of how to call the callback function when having a successful response:
var output = {
id: 1,
name: "First name"
}
var success = RESPONSE(output, null, 200);
callback(success);
In this case, the output, errorOutput and statusCode parameters are included in the response.
If an error occurs in the execution of the action, the callback function with the error response is defined as follows:
var errorOutput = {
error: "Not Found",
message: "The specified user does not exist."
status: 404
}
var error = RESPONSE(null, errorOutput, 404, errorOutput.error);
callback(error);
In this case, the output, errorOutput, statusCode and errorTitle parameters are included in the response.
Correct Implementation |
Incorrect implementation |
---|---|
if (response.success) { else {
In this scenario, the callback is being called once. If the response is successful, or if there is an error. |
if (response.success) {
In this case,t he callback function is being called twice. Instead, use an if-else structure to evaluate if the response is successful or not: |
When defining actions in a connector, it is important to detect and handle correctly the errors that may occur. The following sections illustrate some scenarios to handle errors successfully.
Required inputs
When an input is marked as required, you can verify that it is actually sent. To do so, bz-util offers the validator module, which receives a JSON with the required parameters and validates that they are actually sent within the inputs. In case the validator finds an empty, undefined or null input, it generates a response object with the missing inputs that need to be sent.
The following code illustrate how to define the validator object and how to use it when calling an action.
Validator definition:
{
"parameterName1": "path to parameter in data, ex: data.inputs.input.parameterName1",
"parameterName2": "path to parameter in data, ex: data.inputs.input.parameterName2"
}
Using the validator in an action:
var bizagiUtil = require('bz-util');
var error = bizagiUtil.validator.requiredParameters({
fileId: data.inputs.input.fileId,
destinationPath: data.inputs.input.destinationPath
});
if(error){
LOG.error(['[BOX.'+actionName+']', 'Error:', error]);
return callback(error);
}
Error handling with Promises
A Promise is an object that represents the completion of an asynchronous operation, which could end successfully or with an error. Handling errors within Promises is quite simple; however, bear in mind that a classic try-catch structure will not work.
To handle errors regarding Promises, you have two options:
1.Use directly the catch function provided by the Promise itself:
axios.get(url)
.then((response) => { /* code here */ })
.catch((error) => { /* some error handling */ });
2.implement a try-catch structure using the await function:
try {
let response = await axios.get(url);
} catch (error) {
// some error handling
}
For further information about handling errors in Promises, click here.
Last Updated 1/9/2024 11:58:57 AM