Plugin SDK

Connector SDK

Build custom connectors using the Flowmatic Plugin API. Java-based, type-safe, and hot-reloadable.

Overview

The Plugin SDK (flowmatic-plugin-api) provides the interfaces and context objects you need to create custom connectors. Plugins are loaded at startup from the ./plugins directory and automatically registered in the connector registry.

Java 21+

Modern Java with records and pattern matching

Hot-reload

Drop JARs into /plugins, restart to load

Type-safe

Compile-time checked interfaces

ConnectorPlugin Interface

package io.flowmatic.plugin.api;

public interface ConnectorPlugin {

    /** Return plugin metadata (id, name, version, supported types) */
    PluginInfo getPluginInfo();

    /** Called once on load. Use context for config and services. */
    void initialize(PluginContext context);

    /** Execute the connector logic. Return result as a Map. */
    Map<String, Object> execute(
        String connectorType,
        NodeData nodeData,
        Map<String, Object> executionContext
    ) throws PluginExecutionException;

    /** Called on shutdown for cleanup. */
    void shutdown();

    /** Check if this plugin handles a given connector type. */
    boolean supportsConnector(String connectorType);
}

Quick Start: Custom Connector

1. Define plugin metadata

@Override
public PluginInfo getPluginInfo() {
    return PluginInfo.builder()
        .id("my-custom-connector")
        .name("My Custom Connector")
        .version("1.0.0")
        .description("Integrates with My Service")
        .author("Your Name")
        .supportedConnectorTypes(Set.of("MY_SERVICE"))
        .build();
}

2. Implement the execute method

@Override
public Map<String, Object> execute(
    String connectorType,
    NodeData nodeData,
    Map<String, Object> executionContext
) throws PluginExecutionException {

    // Read configuration from the node
    String apiKey = (String) nodeData.getConfiguration().get("apiKey");
    String endpoint = (String) nodeData.getConfiguration().get("endpoint");

    if (apiKey == null || apiKey.isBlank()) {
        throw new PluginExecutionException(
            "API key is required", "MISSING_CONFIG"
        );
    }

    // Use expression evaluator for dynamic values
    ExpressionEvaluator evaluator = context.getExpressionEvaluator();
    String resolvedEndpoint = evaluator.evaluate(endpoint, executionContext);

    // Call your service...
    Map<String, Object> result = callMyService(resolvedEndpoint, apiKey);

    return Map.of(
        "status", "success",
        "data", result
    );
}

3. Build and deploy

# Build your plugin JAR
./gradlew :my-plugin:build

# Copy to the plugins directory
cp build/libs/my-plugin-1.0.0.jar ./plugins/

# Restart Flowmatic - your connector appears automatically
./gradlew :backend:bootRun

Key SDK Objects

ClassPurpose
ConnectorPluginMain interface to implement for custom connectors
PluginInfoMetadata: id, name, version, supported connector types
NodeDataConfiguration map, node id, name, and connector type
PluginContextAccess to expression evaluator, config properties, plugin directory
ExpressionEvaluatorResolve dynamic expressions like {{input.data.name}}
PluginExecutionExceptionTyped errors with error codes (MISSING_CONFIG, INVALID_INPUT, etc.)