JavaScript flow-node
5 minute read
Overview
The JavaScript plugin, @axway/api-builder-plugin-fn-javascript
, allows the user to execute JavaScript code inside a Flow.
To install the JavaScript plugin, execute the following command:
npm install --no-optional @axway/api-builder-plugin-fn-javascript
For additional getting started information, refer to the Getting Started With API Builder.
Methods
The following sections provide details of the JavaScript flow-node Execute method.
Execute
Allows the execution of JavaScript code and returns the result of the execution as the flow-node’s output.
Flow-node’s parameters
Parameter | Type | Description | Configuration selection | Required |
---|---|---|---|---|
Code | string | A JavaScript function body. Supports `await` and returning promises. | Selector, String | Yes |
Data | any | The value to apply as the `data` argument to the JavaScript code. For objects and arrays, `data` is passed by reference. | Any | No |
Parameter: Code
Note
It is not recommended to provide the code as a Selector. It is a security risk to execute code obtained from unknown sources.The Code
parameter is where you define the JavaScript you would like to execute. The Code should be provided as a String. The Data parameter is fed into the code snippet as the first argument, data
. The second argument of the code, logger,
is the API Builder logger.
Parameter: Data
The Data parameter refers to content which is passed to the JavaScript code. The content is passed as an argument in the code as data
. The parameter can be any data type. For example, you could use $
Selector to access the entire context, or limit it to a specific subset (e.g. to access parameters as parameters - $.params
).
Outputs
Output | Type | Description | Save output value as: |
---|---|---|---|
Next | any | The data returned by the code snippet. If returning a promise, this will be the data that the promise resolves with. | $.result |
Error | any | This output is triggered if the code snippet throws an error or returns a promise which rejects. The output value an object with the error message, or the rejected value. | $.error |
How to use the JavaScript plugin
After the installation of the JavaScript plugin and editing a Flow, you will find the JavaScript flow-node in the Core section:
You can drag and drop the JavaScript flow-node into the Flow Graph to expand its details:
Example 1 - Greet Flow
Here is how you could use the JavaScript flow-node to achieve the same functionality as our Greet Flow example:
First, you would need to determine the data you would like to pass to your function. For the Greet Flow you will need both the $.config
, as the salutation is stored there, and the user’s name, which comes from $.params
.
So let’s pass the entire context with the $
selector and use JavaScript code to format the message as we have seen in the Greet Flow.
We could use a simple template literal to construct the message:
Let’s hook everything up as we have seen before to the success node and bad request node.
Make sure the outputs of the JavaScript flow-node are correctly used within the HTTP flow-nodes. As described above, the default outputs are $.result
and $.error
:
You could invoke your newly created flow through the debugger:
Which would return the already familiar salutation:
Example 2 - Logging
The JavaScript flow-node can also make use of the API Builder logger. You can see the logger as the second argument to the Code
function. As with anything that uses the API Builder logger, only logs at or above the configured LOG_LEVEL of the service will be output to the terminal. See Logging for more details.
Here is how you can add extra debugging to your flow:
This example flow-node calculates the product of the provided array of numbers.
1621337798796 DEBUG [request-id: 9abdf0c2-efb0-4d85-b6cb-3746ea0133f1] Waiting: Calculate product (javascript.1)
1621337798796 DEBUG [request-id: 9abdf0c2-efb0-4d85-b6cb-3746ea0133f1] Invoking: Calculate product (javascript.1), method: Execute
1621337798798 DEBUG [request-id: 9abdf0c2-efb0-4d85-b6cb-3746ea0133f1] Calculate product (javascript.1) route: []
1621337798798 DEBUG [request-id: 9abdf0c2-efb0-4d85-b6cb-3746ea0133f1] Calculate product (javascript.1) writing 120780 to ctx as: $.response
Unfortunately, when debugging, we do not see which numbers are being calculated and only the result. We will add a debug log to show what is going on!
1621337924647 DEBUG [request-id: 29011c0a-317c-456a-ac63-0dfa9f8a7f07] Waiting: Calculate product (javascript.1)
1621337924647 DEBUG [request-id: 29011c0a-317c-456a-ac63-0dfa9f8a7f07] Invoking: Calculate product (javascript.1), method: Execute
1621337924648 DEBUG [request-id: 29011c0a-317c-456a-ac63-0dfa9f8a7f07] Calculate product (javascript.1) Calculating: 1 * 5 * 99 * 244
1621337924648 DEBUG [request-id: 29011c0a-317c-456a-ac63-0dfa9f8a7f07] Calculate product (javascript.1) route: []
1621337924648 DEBUG [request-id: 29011c0a-317c-456a-ac63-0dfa9f8a7f07] Calculate product (javascript.1) writing 120780 to ctx as: $.response
Example 3 - Format Object
Input | Code | Output |
---|---|---|
data = { “firstName”: “Bruce”, “lastName”: “Wayne”, “heroName”: “Batman” }; |
// Maps a hero name to the Universe the character belongs to const heroNamesToUniverseMapper = { ‘Batman’: ‘DC’, ‘Flash’: ‘DC’, ‘Spiderman’: ‘Marvel’, ‘Iron Man’: ‘Marvel’ }; return { heroName: data.heroName, secretName: data.firstName + ’ ’ + data.lastName, universe: heroNamesToUniverseMapper[data.heroName] |
Example 4 - String Concatenation
Input | Code | Output |
---|---|---|
data = { “firstName”: “Bruce”, “lastName”: “Wayne” }; |
return data.firstName + ’ ’ + data.lastName; | “Bruce Wayne” |
data = { “firstName”: “Bruce”, “lastName”: “Wayne” }; |
return `${data.firstName} ${data.lastName}`; | “Bruce Wayne” |
Example 5 - Processing Data
Input | Code | Output |
---|---|---|
data = [“1”,“2”,“3”,“4”,“5”]; | let result = 0; data.forEach(function(element) { const number = parseInt(element); if(number % 2 == 0){ result += number; } }); return result; |
6 |
data = [“1”,“2”,“3”,“4”,“5”]; | return data.map(item => parseInt(item)) .filter(number => number % 2 == 0) .reduce((sum, number) => sum + number); |
6 |
Example 6 - Object Manipulation - Combining two objects
Input | Code | Output |
---|---|---|
data = { “birthYear”: 1989, “name”: “Peter Parker” }; |
const companyDetails = { company: ‘Axway’, companyAddress: ‘Phoenix, US’ }; return Object.assign(data, companyDetails); |
{ “birthYear”: 1989, “name”: “Peter Parker”, “company”: “Axway”, “companyAddress”: “Phoenix, US” } |
Example 7 - Object Manipulation - Merging with spread
Input | Code | Output |
---|---|---|
data = { “birthYear”: 1989, “name”: “Peter Parker” }; |
return { …data, company: ‘Axway’, companyAddress: ‘Phoenix, US’ }; |
{ “birthYear”: 1989, “name”: “Peter Parker”, “company”: “Axway”, “companyAddress”: “Phoenix, US” } |