Axway Flow SDK

The Axway Flow SDK (axway-flow-sdk) is a standalone utility that enables the creation of custom flow-node plugins for API Builder flows. By offering the Axway Flow SDK as a standalone utility, new flow-nodes can be developed and consumed in API Builder without upgrading the version.

Features

The Axway Flow SDK has the following content:

  • CLI tool for starting a new flow-node plugin
  • SDK for building custom modules for API Builder flows

Install

The following command installs the Axway Flow SDK.

npm install -g axway-flow-sdk

Use the Axway Flow SDK

The following generates a new flow-node plugin in the current directory. You can customize the plugin to meet your requirements.

axway-flow -n <node name>
cd <node name>
npm install --no-optional
npm run build

Alternatively, you can use npx to generate a flow-node plugin without installing axway-flow globally.

npx axway-flow -n <node name>
cd <node name>
npm install --no-optional
npm run build

The generated plugin name is prefixed with the required api-builder-plugin- prefix.

The starter project is heavily commented to simplify the process of customizing it. It also comes with the eslint configuration and the mocha unit tests incorporated to help you ensure the quality of your custom flow-node.

encodeURI example

const sdk = require('axway-flow-sdk');

function getFlowNodes() {
	const flownodes = sdk.init(module)
		.add('encodeURI', {
			name: 'Encode URI',
			icon: 'encode.svg',
			description: 'URI encoder'
		})
		.method('encode', {
			name: 'Encode URI',
			description: 'Encodes a URI by replacing each instance of certain characters with UTF-8 encodings.'
		})
		.parameter('uri', {
			type: 'string',
			description: 'The URI to encode.'
		})
		.output('encoded', {
			name: 'Encoded',
			description: 'The encoded URI.',
			context: '$.encodedURI',
			schema: {
				type: 'string'
			}
		})
		.action((req, cb) => {
			cb.encoded(null, encodeURI(req.params.uri));
		});
	return Promise.resolve(flownodes);
}

exports = module.exports = getFlowNodes;

Note that the encodeURI example is returning a function, getFlowNodes, that returns a promise. This allows for the generation of the flow-node to be asynchronous, for example, to allow the loading of content from a remote source. In this example it is used for demonstration purposes only, flownodes could have been returned from getFlowNodes instead.

Type references

In Axway API Builder, it is possible to reference other types. For example, types can be loaded from ./schemas, registered from Models, or registered from service connectors. Any registered schema can be referenced whenever a schema is required.

.parameter('greeting', {
	"$ref": "schema://model/appc.arrowdb/user"
})
.output('next', {
	schema: {
		"$ref": "schema://model/appc.arrowdb/user"
	}
})

Unit test your flow-node plugin

The starter project includes automatically generated unit tests in the ./test directory of your project. The tests are for example purposes and will need to be customized to your specific use case. The SDK provides a mocknode that allows for mock invocations of your flow-nodes methods.

mocknode (flow-nodes)

Mocks an API Builder flow-node using the flow-node generated with NodeBuilder.

Access: public

Parameter Type Description
flownodes NodeBuilder The NodeBuilder object.

Testing a successful output callback

This example uses mocha and promises to check that the flow-node is defined well enough to pass the argument foo to the method method. It also mocks the callback using the defined output of the flow-node and ensures that the method invokes the correct callback.

Note if the flow-node is asynchronous; in other words, returns a promise, the promise must be resolved to get the flow-nodes defined in the plugin. This can simply be done using a before block that waits for the resolved promise.

const flownodesPromise = require('../src');
const { mocknode } = require('axway-flow-sdk');

let flownodes;
before(() => {
	return flownodesPromise.then((resolvedFlownodes) => {
		flownodes = resolvedFlownodes;
	});
});

it('describes a test', () => {
	const args = { foo: undefined };
	return mocknode(flownodes).node('example').invoke('method', args)
		.then((response) => {
			expect(response).to.deep.equal({
				next: [null, 'stuff']
			})
		});
})

Testing an error default callback

This example is similar to the previous example, save that the expectation is that the method will invoke cb('invalid argument') when given an undefined parameter.

const flownodes = require('../src');
const { mocknode } = require('axway-flow-sdk');

it('describes a test', () => {
	const args = { foo: undefined };
	return mocknode(flownodes).node('example').invoke('method', args)
		.then((response) => {
			expect(response).to.deep.equal(['invalid argument'])
		});
})

Local API Builder test

While unit testing is important, it is also necessary to be able to install the custom flow-node plugin into your local API Builder application for testing. This can be achieved by packing the module locally:

cd api-builder-plugin-fn-encodeuri
npm install --no-optional
npm run build
npm pack

This will create a tgz archive (api-builder-plugin-fn-encodeuri-1.0.0.tgz) that can then be installed into your API Builder application.

cd <app-folder>
npm install --no-optional <path to flow node project>/api-builder-plugin-encodeuri-1.0.0.tgz
npm start

Type references

In Axway API Builder, it is possible to reference other types. For example, types can be loaded from ./schemas, registered from models, or registered from service connectors. Any registered schema can be referenced whenever a schema is required.

.parameter('greeting', {
    "$ref": "schema://model/mongo/user"
})
.output('next', {
    schema: {
        "$ref": "schema://model/mongo/user"
    }
})

API Reference

axway-flow-sdk~NodeBuilder

Kind: Inner class of axway-flow-sdk

new NodeBuilder(srcModule, [options])

Parameter Type Default Description
srcModule object   A node module.
[options] object   The options for the builder.
[options.validate] object true This enables parameter validation. Disable if you need to use refs.

nodeBuilder.add(key, [options])

Adds a new flow-node spec and prepares the NodeBuilder to accept the following specification operations:

The key parameter is used to uniquely identify the specification and represents a distinct instance of a flow-node for the flow editor. The key is used as the name unless the name option is provided. The new flow-node will appear in the general category by default, or under the provided category option.

The icon option can be a bmp, jpeg, png, gif, tiff, or svg file. The .method option is used to add a method or methods, and the .output option is used to define an output. The .action option is used to define an action function and finish the specification.

Kind: Instance method of NodeBuilder

Returns: Current NodeBuilder object

Access: Public

Parameter Type Default Description
key

string

  A unique key identifier for the flow-node.
[options]

object

  Options for the flow-node.
[options.name]

string

  A friendly name for the flow-node as it will appear in the UI.
[options.icon]

string

  An icon file.
[options.description]

string

  A description for the flow-node.
[options.category]

string

general A category under which the flow-node will appear in the UI.

Example:

sdk.init(module).add('encodeURI', { icon: 'encode.svg' });

nodeBuilder.method(key, [options])

Adds a new method to the current flow-node specification and prepares the NodeBuilder to accept the following method operations:

The .add(key, [options]) must be called prior to adding a method.

The key uniquely identifies the method for the flow-node and will be used as the name unless the name option is provided.

Kind: Instance method of NodeBuilder

Returns: Current NodeBuilder object

Access: Public

Parameter Type Description
key

string

A unique key identifier for the method.
[options]

object

Options for the method.
[options.name]

string

A friendly name for the method as it will appear in the UI.
[options.description] string A description of the method.

Example:

sdk.init(module).add('encodeURI', { icon: 'encode.svg' })
    .method('encode', { name: 'Encode URI' });

Example (Disable validation):

sdk.init(module, { validation: false }).add('encodeURI', { icon: 'encode.svg' })
	.method('encode', { $ref: '#/definitions/foo' });

nodeBuilder.group(name)

Kind: Instance method of NodeBuilder

Returns: Current NodeBuilder object

Access: Public

Parameter Type Description
name string A unique name for the parameter group as it will appear in the UI.
sdk.init(module).add('encodeURI', { icon: 'encode.svg' })
	.method('encode', { name: 'Encode URI' })
	.group('Advanced')
	.parameter('uri', { type: 'string' });

nodeBuilder.parameter(name, schema, [required])

Adds a new parameter to the current method. Any number of parameters can be added to a method.

The .method(key, [options]) must be called prior to adding a parameter.

The name uniquely identifies the parameter and the schema is a valid JSON Schema definition (both draft-04 and draft-06 are supported).

Kind: Instance method of NodeBuilder

Returns: Current NodeBuilder object

Access: Public

Parameter Type Default Description
name string   A unique name for the parameter as it will appear in the UI.
schema object   A schema used to validate the parameter.
[required] boolean true A flag to indicate the parameter is required or optional.

Example:

sdk.init(module).add('encodeURI', { icon: 'encode.svg' })
    .method('encode', { name: 'Encode URI' })
    .parameter('uri', { type: 'string' });

nodeBuilder.output(key)

Adds a new output to the current method. Any number of outputs can be added to a method, but for usability-sake, you should limit this. The output represents one of the possible callback routes for your method. For example, if your method tested prime numbers, then one output might be prime, and the other not-prime.

The .method(key, [options]) must be called prior to adding an output.

The key uniquely identifies the output route. The schema is a valid JSON Schema definition (both draft-04 and draft-06 are supported). If a schema is not provided, then the output type is effectively any type.

The context is a valid JSON Path and is used as the default by the flow editor. When the output is invoked, the configured context is where the output value will be written.

Kind: Instance method of NodeBuilder

Returns: Current NodeBuilder object

Access: Public

Parameter Type Description
key string A unique key for the output.
[options.name] string A friendly name for the output as it will appear in the UI.
[options.description] string The output description.
[options.context] string The default context string.
[options.schema] object The expected JSON schema for the output value.

Example:

sdk.init(module).add('encodeURI', { icon: 'encode.svg' })
    .method('encode', { name: 'Encode URI' })
    .parameter('uri', { type: 'string' })
    .output('encoded', { context: '$.encodedURI', schema: { type: 'string' } });

nodeBuilder.action(handler)

Assigns an action handler to the current method. The method can only have one action handler. Assigning an action will terminate the current method definition.

Kind: Instance method of NodeBuilder

Returns: Current NodeBuilder object

Access: Public

Parameter Type Description
handler handler The action handler function.

Example:

sdk.init(module).add('encodeURI', { icon: 'encode.svg' })
    .method('encode', { name: 'Encode URI' })
    .parameter('uri', { type: 'string' })
    .output('encoded', { context: '$.encodedURI', schema: { type: 'string' } })
    .action((req, cb) => cb.encoded(null, encodeURI(req.params.uri));

axway-flow-sdk~init(module)

Axway API Builder SDK for creating custom flow-nodes to work with flows.

Kind: Inner method of axway-flow-sdk

Returns: NodeBuilder - A newly constructed NodeBuilder object 

Parameter Type Description
module object The flow-node module.

Example:

const sdk = require('axway-node-sdk');
exports = module.exports = sdk.init(module);

axway-flow-sdk~validate(nodes)

Validates the flow-nodes against the Axway Flow schema.

Kind: Inner method of axway-flow-sdk

Throws: Error - If nodes contain invalid flow-nodes.

Parameter Type Description
nodes NodeBuilder Nodes to validate.

Example:

const nodes = sdk.init(module).add('encodeURI', { icon: 'encode.svg' })
	.method('encode', { name: 'Encode URI' })
	.parameter('uri', { type: 'string' })
	.output('encoded', { context: '$.encodedURI', schema: { type: 'string' } })
	.action((req, cb) => cb.encoded(null, encodeURI(req.params.uri));
sdk.validate(nodes);

Related Links