# Extensibility

Extensibility is a crucial capability for any framework, as it allows developers to add new features and functionality without having to completely rewrite your existing flows. With extensible architecture, developers can write reusable modules and plug-ins that can be easily integrated into the main codebase, saving time and effort, while enhancing the cloud interoperability and mobility capabilities of Kumologica.

In Kumologica there are two types of extensions: middlewares and plugins.

# Middlewares

Middlewares are functions that have access to the request and response objects in the application flow request-response cycle.

Kumologica supports standard Express middlewares that can be used to augment the flow by modularizing cross-cutting concerns that are not part of the business logic.

# Writing middlewares

A middleware is a javascript file that will export a default function that will follow the Express middleware syntax. learn more (opens new window)

module.exports = function (req, res, next) {
    // your code here
    next()
}

# Configuration

In order to utilize middlewares, it is necessary to create a config.json file at the root level of your Kumologica project.

The relative file path of the your middleware(s) to the root project must be specified in the runtime.middlewares property.

The following is the syntax for the config.json file:"

 {
    "version": "0.0.1",
    "runtime": {
        "loglevel": "debug",
        "middlewares": [
            "./middlewares/audit-middleware", 
            "./middlewares/rbac-middleware"
        ]
    }
}

# Error Handling

To terminate a middleware, it is necessary to call next(err) in order to skip the execution of the remaining middlewares and jump directly to Kumologica's default error handling mechanism.

The following is an example of throwing an error within a middleware:

let unauthorized = function (req, res, next) {
    let err = new Error('UnauthorizedError');
    err.statusCode = 401;
    // Forward all the errors to the runtime default error handler
    next(err);    
}

module.exports = unauthorized;

# Plugins Beta

WARNING

Please note that this capability is currently in beta and, due to ongoing development, backwards compatibility may not be guaranteed.

A plugin in Kumologica are reusable lifecycle hooks that can modify or enhance the incoming request, handle the response, or manipulate the messages passing through the flow.

A plugin is a javascript class that can override one of the following methods:

  • onStartFlow(req) Flow has accepted a request.
  • onTerminateFlow(res, payload) Flow has already processed the request and it is about to respond to the client.
  • onErrorFlow(err) Flow has encountered an error.
  • onStartNode(node, msg) Message is about to entered in node.
  • onTerminateNode(node, msg) Message has left the node.
  • onErrorNode(node, err, msg) Message has encountered an error in a given node.

# Example: Metering Plugin

The following snippet is a simple implementation that will print in the console the timing taken by each node during a flow execution:

import { performance } from 'perf_hooks';

class MeteringPlugin {
    protected runtime = null;

    constructor() {

    }
    onStartFlow(req): void {
        performance.mark('flow-start');
    }
    onTerminateFlow(res, payload): void {
        performance.mark('flow-end');
        performance.measure("Flow", "flow-start", "flow-end")
    }
    setRuntime(runtime: any): void {
        this.runtime = runtime;
    }
}

# Configuration

In order to utilize plugins, it is necessary to create a config.json file at the root level of your Kumologica project.

The relative file path of the your middleware(s) to the root project must be specified in the runtime.middlewares property.

The following is the syntax for the config.json file:"

 {
    "version": "0.0.1",
    "runtime": {
        "loglevel": "debug",
        "plugins": [
            "./plugin/metering-plugin"
        ]
    }
}