FlowGram Runtime SDK 是一个面向 Spring Boot 的 Java 内嵌运行时。它提供工作流执行、画布读写、运行状态存储、前端编辑器静态资源和运行调试 API,业务应用引入 starter 后即可获得开箱即用的 FlowGram 编辑页面和后端运行接口。
当前发布版本:
<version>0.1.1</version>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。
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
bizType 和 bizId 会用于调用后端画布接口:
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 会自动注册所有 NodeExecutor 和 ComponentExtension。
如果流程里使用 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 访问策略,不要无条件开放私网访问。
除了通过 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):取消任务。
默认 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 可参考:
flowgram-runtime-sdk-spring-demo/
demo 展示了:
- 引入 starter 后直接访问
/flow/。 - 使用文件实现
CanvasRepository,支持画布保存、读取和历史版本。 - 使用
MemoryRuntimeStore扩展统计运行态写入次数。 - 注册
HttpNodeExecutor。 - 注册自定义
ComponentExtension。 - 启动后输出 FlowGram 编辑器 URL。
需要带上业务参数:
/flow/?bizType=demo&bizId=flow-001
没有 bizType 和 bizId 时,前端不会调用画布存储接口,会使用内置初始数据。
优先检查:
- 当前页面 URL 是否包含正确的
bizType和bizId。 - 自定义
CanvasRepository.save是否真的写入最新 schema。 CanvasRepository.load是否读取同一个bizType + bizId。- 是否存在浏览器旧页面自动保存覆盖了最新版本。
后端接口由 flowgram.api.base-path 控制。前端页面也必须使用同一个 API 前缀。默认 /flowgram/api 开箱即用;如果改成自定义路径,请同步调整前端运行配置或通过 URL 参数传入运行接口前缀。
Central Portal 发布完成后,repo1.maven.org 通常会先同步元数据,搜索站点索引可能再延迟几分钟。以 Maven 仓库元数据为准:
https://repo1.maven.org/maven2/wang/minggen/flowgram/flowgram-runtime-spring-boot-starter/maven-metadata.xml