关于 camunda-connectors-development
面向 Camunda 8 开发者的自定义连接器构建指南,涵盖 JSON 元素模板与 Java SDK 两条路径,并说明出站、入站连接器的区别及部署方式。
主要功能
- 01用 JSON 模板定制协议连接器
- 02通过 Java SDK 开发自定义连接器
- 03构建入站 Webhook、订阅和轮询连接器
- 04配置元素模板与 FEEL 输入
- 05了解连接器注册和托管方式
适用场景
- 01为现有协议连接器添加领域化 Modeler 界面
- 02实现多步骤或专有协议集成
- 03通过外部事件启动或继续流程
- 04将连接器部署到自托管或混合环境
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ camunda/ skills --skill camunda-connectors-development安装后在 Claude Code 中输入/camunda-connectors-development确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
portability.jsonreferences/connector-sdk-inbound.mdconnector-sdk-outbound.mdelement-template-generator.mdelement-template-json.mdprotocol-connector-templates.mdregistration-and-hosting.md详细介绍
Camunda Connectors 开发
当 OOTB 目录不包含所需集成时,可构建自定义 Camunda 8 连接器。两条不同路径使用相同的元素模板界面,但是否需要编写 Java 则有所不同。
前提条件
- 可连接的 Camunda 8.8+ 集群,用于测试(本地 c8run、SaaS 或 Self-Managed——参见 camunda-c8ctl)
- 路径 A:除集群外无其他要求——JSON 模板由手动编写,并使用
c8ctl element-template get <id>获取基础 OOTB 模板作为起点 - 路径 B:Java 17+、Maven 3.8+(或同等版本的 Gradle),以及用于运行生成的连接器 JAR 的 JVM 托管选项——参见 camunda-development,了解如何在本地安装 JDK / Maven 工具链
交叉参考
- camunda-development:首先使用它来判断构建连接器是否合适(而不是使用 OOTB 连接器或作业 Worker)
- camunda-connectors:用于发现和应用 OOTB 连接器——这里要扩展的目录
- camunda-job-workers:当集成逻辑应属于应用程序代码而非可复用连接器时使用(决策矩阵中的路径 C;Worker 仅支持出站)
- camunda-bpmn:用于编写连接器所附着的 BPMN 元素(出站使用服务任务,入站使用开始事件/中间事件/边界事件或接收任务)
- camunda-feel:用于预填模板属性以及绑定输入/输出映射的 FEEL 表达式
- camunda-process-test:用于驱动流程通过自定义连接器的端到端测试
何时编写自定义连接器
首先查看 camunda-development。此处适用的决策矩阵简述如下:
- OOTB 连接器已满足需求 → 使用 OOTB 模板。结束。
- 通过常见协议进行单次 API 调用(REST、SOAP、GraphQL、Kafka、RabbitMQ、AWS SQS/SNS,……),且可以接受 Java → 路径 A:在现有协议连接器上自定义 JSON 模板。无需 Java,也无需额外部署。
- 多步骤编排、专有协议、非 HTTP I/O 或大量业务逻辑,且已有 Java 技术栈 → 路径 B:通过 Connectors SDK 编写自定义 Java 连接器。
- 非 Java SDK,或逻辑属于现有应用程序 → 编写作业 Worker。Worker 无法处理入站触发器。
出站与入站
两个方向并不对称——只有入站连接器能够让外部事件从引擎外部驱动流程。Worker 无法替代入站连接器;这部分由连接器框架负责。
- 出站:流程令牌到达服务任务,连接器调用外部系统,结果作为变量返回。路径 A 和路径 B 都支持出站。
- 入站:外部系统触发事件(HTTP 请求、消息队列投递、定时轮询)。连接器将事件关联到流程——启动新实例(开始事件),或继续等待中的实例(中间捕获事件、边界事件、消息开始事件、接收任务)。仅路径 B 支持——路径 A 的协议模板构建在出站协议连接器之上;入站 Webhook 连接器有自己的 OOTB 模板,可直接自定义。
三种入站类型分别由不同的 SDK 形式负责:
- Webhook — 运行时会为每个已部署流程公开一个 HTTP 端点;外部系统向其发送 POST 请求。
- 订阅 — 运行时会打开与消息代理的连接并消费消息(Kafka、RabbitMQ、AWS SQS,……)。
- 轮询 — 运行时会代表流程定期调用外部系统。
参见 references/connector-sdk-inbound.md,了解生命周期(activate / deactivate)以及将事件送入引擎的 correlateWithResult 约定。
选择路径
| 路径 | 选择时机 |
|---|---|
| 路径 A — 协议连接器上的纯 JSON 模板 (参考) | 适用于通过受支持协议(REST/SOAP/GraphQL/Kafka/RabbitMQ/AWS 消息传递)进行单次调用的出站集成。无需编写 Java,即可在 Modeler 中提供符合领域需求的界面。以单个 JSON 文件的形式提交到代码库。 |
| 路径 B — 通过 SDK 构建自定义 Java 连接器 ([参考:出站、入站]) | 适用于路径 A 无法实现的情况:多步编排、专有协议、非 HTTP I/O、入站触发器(webhook/订阅/轮询),或需要作为带版本的制品在多个流程间复用的逻辑。需要 Java 17+,并且需要决定托管方式。 |
当路径 A 的协议不匹配,而路径 B 又过于繁重时,JSON 模板也是为作业工作器提供完善 Modeler 界面的自然选择——使用 references/element-template-json.md 手动编写模板,并将其绑定到工作器的 zeebe:taskDefinition type。这仍然是工作器,而不是连接器。
元素模板 — 通用界面
两种路径都会生成一个元素模板 JSON 文件。两者的架构相同,区别在于文件的编写方式:
- 路径 A:使用
c8ctl element-template get <id>获取协议连接器已发布的模板作为起点,然后进行自定义——通过"type": "Hidden"隐藏基础设施属性(URL、method、auth),使用 FEEL 为其预填充值,并仅公开领域特定的输入。 - 路径 B:使用
@ElementTemplate注解连接器类,并让 Maven 插件在构建期间生成 JSON(references/element-template-generator.md),或手动编写。
专门定制任何 OOTB 模板,而不仅仅是协议连接器模板
“隐藏基础设施属性,仅公开领域输入”这一模式适用于任何 OOTB 模板,而不仅仅是通用协议模板。只要定制后的模板仍会写入底层作业工作器所需的输入映射(zeebe:taskDefinition type 和 zeebe:input 的结构就是数据契约),工作器接收到的负载就不会改变——只有 Modeler 界面不同。
camunda/connectors 中的具体示例:
connectors/openai/element-templates/openai-connector.json— 完整的 OpenAI 模板;定制版本可以隐藏 system prompt 或模型选择器,仅公开领域输入。connectors/github/element-templates/github-connector.json— 为底层作业工作器提供专门定制的界面。connectors/github/element-templates/github-webhook-connector-receive.json— 将通用 webhook 入站连接器呈现为 GitHub 专用的 webhook 界面。connectors/hugging-face/element-templates/hugging-face-connector.json— 为底层 REST 调用提供符合 Hugging Face 风格的界面。
使用 c8ctl element-template get <id> 获取基础模板,然后隐藏、硬编码或重命名属性,同时保留工作器读取的绑定。
references/element-template-json.md 是两种路径共用的架构参考,涵盖属性类型、绑定类型、FEEL/约束/条件/生成值功能,以及适用于各种 BPMN 附加位置的模板变体。
**属性顺序规则:**在某个属性的 FEEL
value中使用的属性,必须在properties数组中排在其前面。引用顺序不正确时,求值会静默返回null。此规则同样适用于路径 A 的自定义和路径 B 的手动编写模板。
共享设施(路径 A 和路径 B)
- 密钥 — 元素模板和 Java 代码会在执行时解析
{{secrets.NAME}}占位符。切勿将密钥存储在 BPMN、模板默认值或硬编码字符串中。独立运行时默认从SECRET_*环境变量读取(8.9+)。 - 内置函数 — 模板默认值和 FEEL 输入可以调用
getText、base64和createLink等内置函数,在连接器接收值之前对其进行转换。 - Camunda 文档 — 生成或使用二进制内容(PDF、图片)的连接器可原生处理 Camunda 文档;工作器必须自行配置相关流程。
- 结果变量 / 结果表达式 / 错误表达式 — 两条路径都会通过元素模板标头提供标准的 输出映射 组(
resultVariable、resultExpression)和 错误处理 组(errorExpression)。请参阅references/element-template-json.md了解绑定结构。
注册与托管
路径 B 有一项路径 A 没有的托管决策 — JAR 必须在某处运行。references/registration-and-hosting.md 介绍了四种选项:
- SaaS 托管运行时 — Camunda 运行标准连接器;托管运行时不支持自定义 JAR,因此在 SaaS 上使用路径 B 需要采用混合模式(见下文)。
- 自托管独立运行时 — 使用
camunda/connectors:X.Y.ZDocker 镜像,并将自定义连接器 JAR 挂载到其应用程序目录中。 - 自托管嵌入式运行时 — 使用
spring-boot-starter-camunda-connectorsstarter 的 Spring Boot 应用程序;由你的应用程序同时托管连接器和你自己的业务代码。 - 混合模式 — 独立运行时在你的环境中运行,但连接到 SaaS 集群。当引擎为 SaaS,而连接器需要在你的网络边界内运行时(访问私有网络、使用本地部署的依赖项、自定义 JAR),必须采用此模式。
SPI 注册与 Spring Bean 注册独立于托管方式,但会对托管方式构成限制。 SPI 注册会写入 META-INF/services/... 文件(Maven 插件的默认行为),并可在独立运行时中使用。Spring Bean 注册(在连接器类上使用 @Component)需要嵌入式 Spring Boot 运行时,并且需要在 Maven 插件中设置 <writeMetaInfFileGeneration>false</writeMetaInfFileGeneration> 来禁止生成 SPI 文件 — 两种机制同时注册同一个类会导致重复发现。
混合模板
如果路径 B 将通过独立运行时连接到 SaaS 集群运行(混合托管),Maven 插件的 <generateHybridTemplates>true</generateHybridTemplates> 标志会为每个连接器生成一个配套的 *-hybrid.json 模板。混合模板会将连接器的任务类型切换为作业工作器样式的绑定,使 SaaS 引擎能够获取作业并将其路由到独立运行时。若未启用此标志,将标准模板部署到 SaaS 会导致运行时永远无法收到作业。
常见陷阱
- 凭训练记忆编造模板 ID 或属性名称——在代码或文档中写入任何 ID、分组或属性前,请使用
c8ctl element-template search "<keyword>"和c8ctl element-template get-properties <id>对照实时 OOTB 目录进行核实。 - 使用 Spring Bean 注册时忘记添加
<writeMetaInfFileGeneration>false</writeMetaInfFileGeneration>——SPI 文件和@Component会重复注册同一个类;运行时会实例化两个对象,后者会静默地覆盖前者。 - 字段顺序错误——某个属性的 FEEL
value引用了声明在它之后的同级属性时,运行时求值结果会是null。Modeler 不会标出此问题;连接器只会收到空输入。 - 在 SaaS 上独立运行时跳过 Hybrid 模板——标准模板的任务类型无法从 SaaS 路由到独立运行时。请设置
<generateHybridTemplates>true</generateHybridTemplates>并部署-hybrid变体。 - 在不支持的协议上使用 Path A——Path A 的适用范围仅限协议连接器目录中的协议(REST、SOAP、GraphQL、Kafka、RabbitMQ、AWS 消息传递)。对于“通过 TCP 传输的自定义二进制协议”模板,没有可供叠加的基础;请改用 Path B。
- 把入站 Webhook 当作作业工作器——入站连接器会在流程定义部署时激活,并在移除部署时停用;没有需要轮询的实例级作业。其生命周期是
activate(InboundConnectorContext)/deactivate(),而不是每个作业对应一个处理器。
参考资料
详情请参阅 references/ 中的文档:
- protocol-connector-templates.md — Path A 操作指南:通过 c8ctl 获取基础模板、隐藏 URL/方法/身份验证、FEEL 预填、自定义分组、REST Countries 示例,以及指向模板生成器工具的简要链接
- connector-sdk-outbound.md —
OutboundConnectorProvider+@Operation(现代方式)、OutboundConnectorFunction(旧版方式)、@Variable/@Header、ConnectorException、Jakarta Validation - connector-sdk-inbound.md —
InboundConnectorExecutable、三种形式、生命周期、correlateWithResult/CorrelationResult - element-template-json.md — 架构参考:顶层字段、属性类型、绑定类型、属性特性、每种 BPMN 附加方式对应的模板变体
- element-template-generator.md — Maven 插件配置、
@ElementTemplate注解、generateHybridTemplates、versionHistoryEnabled、writeMetaInfFileGeneration - registration-and-hosting.md — SPI 与 Spring Bean 注册;SaaS / SM 独立部署 / SM 嵌入式 / Hybrid 托管模式