工作流基础
工作流概述
工作流文件是一个流程的具体实现,其基于Groovy Script 实现、ApiFlow以此为基础进行封装和约束,工作流代码必须遵守Script的基本语法 、同时遵守ApiFlow DSL语法规范。
工作流基本结构
- 初始模块:用于初始流程,仅在流程加载时执行一次。语法是
init { }初始逻辑写在闭包中。初始模块必须存在且只能有一个、必须写在DSL文件的开头。 - 任务定义:定义一个任务,由任务名、任务声明方法、任务参数组成。一个DSL文件中可以定义1到多个任务。
- 流程数据定义:定义一个数据项,由名称与值组成。如
userInfo = [ name:"小明"]。一个DSL文件中可以定义0到多个数据项。 - 模板函数定义:定义一个函数 ,符合groovy 函数定义规则如:
def sendMsg(msg){ }。一个DSL文件中可以定义0到多个模板函数。 - 编排模块:指令编排区域,其语法是
start { }该模块为结构化的内容,只能编写DSL定义的编排指令,不能执行groovy中的其它代码. 如if、for等。编排模块必须存在且只能有一个必须写在dsl文件的最后,否则会导致返回结果错乱。 - 销毁模块:仅流程销毁时执行一次,语法是
destroy { }。当前暂未实现为保留模块。
基本结构示例
// 初始模块 必须写在最前端
init {
listen webhook on "/test" // web hook触发器
}
userInfo= [ id:0, name:"小明" ] // 定义数据
def getUser(id){ // 定义模板函数
userInfo[0]
}
// 定义CODE任务
task1 = CODE {
"hello ${userInfo.name} welcome apiFlow"
}
// 编排模块 必须写在最后
start {
run task1 // 执行任务
}DSL 结构规范
工作流文件本质上是Groovy Script文件,原本是可编写任意代码,但为了控制复杂度简化编排流程,所以对DSL的部分结构进行了限制,对应规范和建议如下:
dsl文件最外层只能编写初始模块、任务定义、数据定义、模板函数定义、编排模块5种结构项,并且严格按照这5种结构项的规范编写 ,不能编写其它代码如:
println等。不建议直接编写
import导入外部类,这样导致整个工作流变得复杂不可控。应该通过app来引入第三方资源,或将复杂逻辑封装在app中,尽量以任务方式对工作流提供,简单的可以通过函数进行提供。无需编写
package指定包名,若不同目录下出现相同的文件名,ApiFlow会基于其所在的路径进行区分。在次强调
start{ }编排模块中不能编写任何除DSL指令以外的任何代码,因为该模块是完全结构化的,目的是该模块可能会基于用户拖拽流程图自动生成,这样就会覆盖指令之外的代码。不建议在DSL文件中编写
class类,为简化编排工作流中的对象都是弱类型,需在开发调式时确认类型。
工作流基本组成元素
- 上下文隐式对象:无须在DSL中声明,在流程初始化时或流程执行的时候自动注入到上下文中如:
config、input、log等。在DSL文件中可以直接获取隐式对象。 - 触发器:用于监听指定事件然后触发当前流程。常见触发器有定时触发器、webhook触发器等。触发器只能写在
init { }初始模块中,一个工作流文件可以定义0到多个触发器。 - 任务: 指流程中一个具体的步骤,会经历定义、初始化、执行三个阶段。一个任务不能被执行两次,目的是为了防止任务上次执行的结果与参数被覆盖。
- 编排指令:指示任务执行的方式,基本执行指令有:
run普通执行、when执行并判断结果、async异步执行。指令通常都会有参数,其类型包括任务或闭包。闭包表示一组执行指令。编排指令只能写在start { }编排模块中。指令执行本质上就是groovy的方法调用。 - 流程数据: 定义与流程相关的变量,可在任务执行过程中被修改值,其作用范围是一个流程执行生命周期,流程一但结束将会被GC回收。
- 模板函数: 流程中一些重复逻辑或任务定义可封装成一个模板函数,从而简化流程编写工作。
上下文隐式对象
为自动注入流程的对象,可直接DSL中获取无需提前声明。每个隐式对象都有其作用范围比如:input只能在流程执行的时候获取,不能在初始化的时候获取,而config对象无论是初始化还是执行都可以获取。
对象作用范围
- 流程初始化时 只能在初始模块
init { }中引用 - 流程运行时 运行一次具体的流程前注入,可在除
init { }以及destory { }之外的地方引用 - 全局 可在任何时候引用,包括流程初始化以及流程运行时。
基础隐式对象列表
| 类型 | 作用范围 | 描述 | |
|---|---|---|---|
| config | Map | 全局 | 全局配置,获取config.groovy中的内容,对象为只读的 |
| webhook | enum | 流程初始化时 | 用于标识webhook触发器 |
| cron | enum | 流程初始化时 | 用于标识cron定时任务触发器 |
| input | Map | 流程运行时 | 输入参数,指进入流程时所带的参数, |
| log | Slf4j | 流程运行时 | 日志对象 |
| _flowId | String | 流程运行时 | 流程ID,标识流程运行时的唯一id |
| _flowPath | String | 全局 | 流程路径,唯识当前DSL文件的唯一路径 |
| _context | Map | 流程运行时 | 表示流程上下文、保留对象 |
注意事项
- 以上全部对象均为只读不可修改,包括其内部属性也不建议修改。
- 编写的DSL代码时一定要避免与隐式对象的关键字冲突。如任务命名、数据项名称等。