Skip to content

minggen/flowgram-runtime-sdk

Repository files navigation

FlowGram Runtime SDK

FlowGram Runtime SDK 是一个面向 Spring Boot 的 Java 内嵌运行时。它提供工作流执行、画布读写、运行状态存储、前端编辑器静态资源和运行调试 API,业务应用引入 starter 后即可获得开箱即用的 FlowGram 编辑页面和后端运行接口。

当前发布版本:

<version>0.1.1</version>

快速接入

1. 添加依赖

Spring Boot 应用只需要引入 starter:

<dependency>
  <groupId>wang.minggen.flowgram</groupId>
  <artifactId>flowgram-runtime-spring-boot-starter</artifactId>
  <version>0.1.1</version>
</dependency>

starter 会自动装配:

  • WorkflowRuntime:工作流运行时。
  • FlowRuntimeBridge:前后端桥接层。
  • FlowgramRuntimeController:画布、任务、组件等统一 API。
  • FlowgramEmbeddedRuntimeController:内嵌前端运行调试 API。
  • FlowgramEditorIndexController:内嵌 FlowGram 编辑器入口。
  • 默认 RuntimeStore:基于内存的 MemoryRuntimeStore
  • 默认 CanvasRepository:基于内存的 InMemoryCanvasRepository

2. 启动 Spring Boot

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class DemoApplication {
  public static void main(String[] args) {
    SpringApplication.run(DemoApplication.class, args);
  }
}

启动后默认访问:

http://127.0.0.1:8080/flow/

带业务参数打开画布:

http://127.0.0.1:8080/flow/?bizType=demo&bizId=flow-001

bizTypebizId 会用于调用后端画布接口:

GET  /flowgram/api/canvas?bizType=demo&bizId=flow-001
POST /flowgram/api/canvas

常用配置

flowgram:
  editor:
    enabled: true
    path: /flow
  api:
    base-path: /flowgram/api
  runtime:
    run-timeout-ms: 30000
    max-execution-steps: 1000
    script-cache-size: 128
    default-node-timeout-ms: 0
  store:
    type: memory
  security:
    debug-server-enabled: false
    debug-server-host: 127.0.0.1
    debug-server-port: 18081
    debug-server-context-path: /api/runtime
    debug-server-await-timeout-ms: 30000

说明:

  • flowgram.editor.path:编辑器页面入口,默认 /flow
  • flowgram.editor.enabled:是否启用内嵌编辑器入口。
  • flowgram.api.base-path:后端 API 前缀,默认 /flowgram/api
  • flowgram.runtime.*:运行超时、最大执行步数、脚本缓存等运行时参数。
  • flowgram.store.type:当前默认内存存储,业务方可以通过自定义 Bean 替换实际存储实现。
  • flowgram.security.debug-server-*:独立 debug server 配置,默认关闭。

默认路径下,前端静态资源和后端接口可以直接配合使用。如果修改 flowgram.api.base-path,需要确保前端运行时请求也使用相同前缀。

画布存储扩展

默认 CanvasRepository 是内存实现,适合本地验证。生产或 demo 文件存储可以自定义 Bean 覆盖默认实现:

import org.springframework.stereotype.Component;
import wang.minggen.flowgram.runtime.bridge.BridgeCanvas;
import wang.minggen.flowgram.runtime.bridge.CanvasQuery;
import wang.minggen.flowgram.runtime.bridge.CanvasRepository;
import wang.minggen.flowgram.runtime.bridge.CanvasVersion;

import java.util.Collections;
import java.util.List;

@Component
public class FileCanvasRepository implements CanvasRepository {
  @Override
  public void save(BridgeCanvas canvas) {
    // 按 bizType + bizId 保存 canvas.getSchema()
  }

  @Override
  public BridgeCanvas load(String bizType, String bizId) {
    // 返回最近一次保存的画布
    return null;
  }

  @Override
  public List<BridgeCanvas> list(CanvasQuery query) {
    return Collections.emptyList();
  }

  @Override
  public List<CanvasVersion> history(String bizType, String bizId) {
    return Collections.emptyList();
  }
}

接口约定:

  • save(BridgeCanvas canvas):保存画布。
  • load(String bizType, String bizId):读取最新画布。
  • list(CanvasQuery query):可选,画布列表。
  • delete(String bizType, String bizId):可选,删除画布。
  • history(String bizType, String bizId):可选,历史版本。
  • loadVersion(String bizType, String bizId, String version):可选,读取指定版本。

运行时存储扩展

RuntimeStore 是低语义运行时存储 SPI,用于任务状态、日志、事件、取消标记等运行态数据。默认实现是 MemoryRuntimeStore。如果要接入 Redis、数据库或分布式缓存,实现并声明一个 Bean 即可:

import org.springframework.stereotype.Component;
import wang.minggen.flowgram.runtime.store.RuntimeStore;

import java.time.Duration;
import java.util.List;

@Component
public class RedisRuntimeStore implements RuntimeStore {
  @Override
  public void put(String key, Object value) {}

  @Override
  public void put(String key, Object value, Duration ttl) {}

  @Override
  public Object get(String key) {
    return null;
  }

  @Override
  public Object remove(String key) {
    return null;
  }

  @Override
  public boolean setIfAbsent(String key, Object value, Duration ttl) {
    return false;
  }

  @Override
  public boolean compareAndDelete(String key, Object expectedValue) {
    return false;
  }

  @Override
  public void append(String key, Object value) {}

  @Override
  public List<Object> range(String key, long start, long end) {
    return java.util.Collections.emptyList();
  }

  @Override
  public void clearPrefix(String prefix) {}

  @Override
  public void clear() {}
}

节点和组件扩展

如果一个节点既要出现在前端组件面板,又要在后端运行时执行,推荐实现 ComponentExtension

import org.springframework.stereotype.Component;
import wang.minggen.flowgram.runtime.bridge.ComponentDefinition;
import wang.minggen.flowgram.runtime.bridge.ComponentExtension;
import wang.minggen.flowgram.runtime.node.ExecutionContext;
import wang.minggen.flowgram.runtime.node.ExecutionResult;
import wang.minggen.flowgram.runtime.node.NodeExecutor;

import java.util.LinkedHashMap;
import java.util.Map;

@Component
public class UppercaseComponentExtension implements ComponentExtension {
  @Override
  public ComponentDefinition definition() {
    return ComponentDefinition.builder()
        .type("uppercase")
        .category("demo")
        .title("Uppercase")
        .description("Convert name to uppercase.")
        .build();
  }

  @Override
  public NodeExecutor executor() {
    return new NodeExecutor() {
      @Override
      public String type() {
        return "uppercase";
      }

      @Override
      public ExecutionResult execute(ExecutionContext context) {
        Map<String, Object> outputs = new LinkedHashMap<String, Object>();
        outputs.put("name", String.valueOf(context.getInputs().get("name")).toUpperCase());
        return new ExecutionResult(outputs);
      }
    };
  }
}

如果只需要运行时执行器,也可以直接声明 NodeExecutor Bean。starter 会自动注册所有 NodeExecutorComponentExtension

内置 HTTP 节点

如果流程里使用 HTTP 节点,可以注册允许策略不同的执行器。例如 demo 中允许访问内网地址:

import org.springframework.context.annotation.Bean;
import wang.minggen.flowgram.runtime.node.NodeExecutor;
import wang.minggen.flowgram.runtime.node.builtin.ApacheRuntimeHttpClient;
import wang.minggen.flowgram.runtime.node.builtin.HttpClientOptions;
import wang.minggen.flowgram.runtime.node.builtin.HttpNodeExecutor;

@Bean
public NodeExecutor httpNodeExecutor() {
  return new HttpNodeExecutor(new ApacheRuntimeHttpClient(HttpClientOptions.builder()
      .allowPrivateNetwork(true)
      .build()));
}

生产环境建议根据安全要求配置 HTTP 访问策略,不要无条件开放私网访问。

直接使用运行时 API

除了通过 HTTP 接口调用,也可以在业务代码中注入 WorkflowRuntime

import org.springframework.stereotype.Service;
import wang.minggen.flowgram.runtime.api.TaskRunInput;
import wang.minggen.flowgram.runtime.api.WorkflowRuntime;
import wang.minggen.flowgram.runtime.schema.WorkflowSchema;

import java.util.Map;

@Service
public class FlowService {
  private final WorkflowRuntime runtime;

  public FlowService(WorkflowRuntime runtime) {
    this.runtime = runtime;
  }

  public Map<String, Object> run(WorkflowSchema schema, Map<String, Object> inputs) throws Exception {
    String taskID = runtime.run(new TaskRunInput(schema, inputs));
    return runtime.awaitResult(taskID, 30000L);
  }
}

常用方法:

  • run(TaskRunInput input):运行完整流程,返回 taskID。
  • runNode(NodeRunInput input):运行单个节点。
  • awaitResult(String taskID, long timeoutMs):等待结果。
  • result(String taskID):读取结果。
  • validate(WorkflowSchema schema):校验流程。
  • report/logs/events/canvasState:读取运行报告、日志、事件和画布状态。
  • cancel(String taskID):取消任务。

HTTP API

默认 API 前缀:/flowgram/api

画布接口:

GET    /flowgram/api/canvas?bizType={bizType}&bizId={bizId}
POST   /flowgram/api/canvas
GET    /flowgram/api/canvas/list
GET    /flowgram/api/canvas/history?bizType={bizType}&bizId={bizId}
GET    /flowgram/api/canvas/version?bizType={bizType}&bizId={bizId}&version={version}
DELETE /flowgram/api/canvas?bizType={bizType}&bizId={bizId}

任务接口:

POST /flowgram/api/tasks/run
POST /flowgram/api/tasks/run-node
POST /flowgram/api/tasks/{taskID}/cancel
GET  /flowgram/api/tasks/{taskID}/result
GET  /flowgram/api/tasks/{taskID}/report
GET  /flowgram/api/tasks/{taskID}/logs
GET  /flowgram/api/tasks/{taskID}/events
GET  /flowgram/api/tasks/{taskID}/canvas-state

内嵌编辑器运行调试接口:

POST /flowgram/api/runtime/validate
POST /flowgram/api/runtime/run
POST /flowgram/api/runtime/node/run
GET  /flowgram/api/runtime/result?taskID={taskID}
GET  /flowgram/api/runtime/report?taskID={taskID}
POST /flowgram/api/runtime/cancel
GET  /flowgram/api/runtime/components

组件接口:

GET /flowgram/api/components?bizType={bizType}

Demo 参考

本仓库配套 demo 可参考:

flowgram-runtime-sdk-spring-demo/

demo 展示了:

  • 引入 starter 后直接访问 /flow/
  • 使用文件实现 CanvasRepository,支持画布保存、读取和历史版本。
  • 使用 MemoryRuntimeStore 扩展统计运行态写入次数。
  • 注册 HttpNodeExecutor
  • 注册自定义 ComponentExtension
  • 启动后输出 FlowGram 编辑器 URL。

常见问题

1. 为什么访问 /flow/ 没加载我的画布?

需要带上业务参数:

/flow/?bizType=demo&bizId=flow-001

没有 bizTypebizId 时,前端不会调用画布存储接口,会使用内置初始数据。

2. 保存返回成功,但刷新不是最新内容?

优先检查:

  • 当前页面 URL 是否包含正确的 bizTypebizId
  • 自定义 CanvasRepository.save 是否真的写入最新 schema。
  • CanvasRepository.load 是否读取同一个 bizType + bizId
  • 是否存在浏览器旧页面自动保存覆盖了最新版本。

3. 修改 API 前缀后前端请求不一致怎么办?

后端接口由 flowgram.api.base-path 控制。前端页面也必须使用同一个 API 前缀。默认 /flowgram/api 开箱即用;如果改成自定义路径,请同步调整前端运行配置或通过 URL 参数传入运行接口前缀。

4. 中央仓库发布后为什么搜索不到最新版本?

Central Portal 发布完成后,repo1.maven.org 通常会先同步元数据,搜索站点索引可能再延迟几分钟。以 Maven 仓库元数据为准:

https://repo1.maven.org/maven2/wang/minggen/flowgram/flowgram-runtime-spring-boot-starter/maven-metadata.xml

About

No description, website, or topics provided.

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors