输入和输出
概述
工作流开始运行时,会接收用户指定的输入数据,并将数据传递至工作流的开始节点,即 start
所指向的节点。在后续的执行中,每个节点都接收上一个节点的输出作为自己的输入,并在执行结束后,继续将自己的输出传给下一个节点。所有的输入输出数据均为 JSON 格式。本节将为您介绍如何处理节点的输入输出数据。

工作流的输入与输出
- workflow 的输入由用户提供,如果用户未提供输入,那么使用
"{}"
作为默认输入。 - workflow 的输出是最后一个节点的输出。
节点的输入与输出
workflow 的输入作为 start 节点的输入,当一个节点执行结束后,它的输出会成为下一个节点的输入。
节点可以通过 stateDataFilter
处理上一个节点传入的输入数据,和传给下一个节点的输出数据。operation 节点还可以通过 actionDataFilter
定义调用云函数时的输入,和处理云函数的返回结果,比如把节点输入数据的其中一部分作为 payload 去调用云函数,云函数返回结果后只取出其中的一部分放入节点数据里。
stateDataFilter
和 actionDataFilter
都是节点的可选参数,节点若不定义则不对输入输出做其它处理。
stateDataFilter
参数 | 类型 | 描述 |
---|---|---|
input(可选) | string | jq 表达式,在执行 state 前过滤输入 |
output(可选) | string | jq 表达式,在 state 结束前过滤输出 |
示例:
工作流的定义如下
1name: demo
2start: hello
3description: "从输入数据中取出 apple 对应的值"
4states:
5 - type: wait
6 name: hello
7 stateDataFilter:
8 input: ".fruits"
9 output: "{res: .apple}"
10 seconds: 2
11 end: true
假定工作流的输入数据为
1{
2 "fruits": {
3 "apple": 7,
4 "banana": 10
5 },
6 "vegetables": ["potato", "tomato", "carrot"]
7}
工作流的处理流程如下:
1、收到执行请求和输入数据,找到开始节点 hello,将数据传递给 hello;
2、hello 根据 stateDataFilter
的 input
参数处理输入数据,处理结果作为自己节点数据,结果为
1{
2 "apple": 7,
3 "banama" : 10
4}
3、hello 节点执行 wait 逻辑,等待2秒钟;
4、hello 节点操作结束,根据 stateDataFilter
的 output
参数处理输出数据,结果为
1{
2 "res": 7
3}
5、由于 hello 节点之后没有其它节点,因次 hello 执行结束后整个工作流就结束了,工作流的输出即上一步中的结果。
actionDataFilter
在 operation 节点中调用函数计算等公有云服务时,可以通过这个 filter 定义传给云服务的参数,也能对服务返回的结果进一步提取筛选,并加入到节点数据中。
参数 | 类型 | 描述 |
---|---|---|
fromStateData(可选) | string | jq 表达式,从节点数据中过滤部分数据传给云服务 |
results(可选) | string | jq 表达式,对调用云服务返回的结果进一步过滤,筛选出想要的数据 |
toStateData(可选) | string | jq 表达式,把 results 的结果添加/合并到 state data 的某个字段内, 若未指定则放入节点数据的顶层 |
useResults(可选) | bool | 是否把云服务返回的结果放入节点数据内,默认为 true |
示例:
1name: demo
2start: hello
3description: "从输入数据中取出 apple 对应的值"
4states:
5 - type: operation
6 name: hello
7 actionDataFilter:
8 fromStateData: "{ stateInput: .hello }"
9 results: "[ .breads[0], .pasta[1] ]"
10 toStateData": ".itemsToBuyAtStore"
11 resource: "brn:cfc:bj:123456:function:test:$LATEST"
12 end: true
假定本次工作流的输入为{"hello":"world"}
,函数的返回为
1{
2 "breads": ["baguette", "brioche", "rye"],
3 "pasta": [ "penne", "spaghetti", "ravioli"]
4}
那么工作流的处理流程大致如下:
1、收到执行请求和输入数据,找到开始节点 hello,将输入数据 {"hello":"world"}
传递给 hello;
2、hello 节点内没有定义 stateDataFilter
,因此不执行输入预处理;
3、hello 节点内定义了 actionDataFilter
,根据 fromStateData
参数执行数据处理,得到 {"stateInput": "world"}
;
4、hello 节点将上一步得到的结果作为 payload 去调用函数;
5、函数返回结果后,根据 actionDataFilter
的 results
参数处理函数返回,结果为 ["baguette", "spaghetti"]
;
6、根据 actionDataFilter
的 toStateData
参数继续处理,把 results
的结果放到节点数据的 itemsToBuyAtStore
字段(没有则创建),最终节点数据为
1{
2 "hello": "world",
3 "itemsToBuyAtStore": ["baguette", "spaghetti"]
4}
7、hello 节点内没有定义 stateDataFilter
,因此不执行输出预处理,工作流执行结束。
jq 表达式
从上文的介绍中可知,节点数据的过滤、处理都依靠 jq 表达式,这里展示出常用的 jq 操作。源数据如下:
1{
2 "store": {
3 "book": [
4 {
5 "category": "reference",
6 "author": "Nigel Rees",
7 "title": "Sayings of the Century",
8 "price": 8.95
9 },
10 {
11 "category": "fiction",
12 "author": "Evelyn Waugh",
13 "title": "Sword of Honour",
14 "price": 12.99
15 },
16 {
17 "category": "fiction",
18 "author": "Herman Melville",
19 "title": "Moby Dick",
20 "isbn": "0-553-21311-3",
21 "price": 8.99
22 },
23 {
24 "category": "fiction",
25 "author": "J. R. R. Tolkien",
26 "title": "The Lord of the Rings",
27 "isbn": "0-395-19395-8",
28 "price": 22.99
29 }
30 ],
31 "bicycle": {
32 "color": "red",
33 "price": 19.95
34 }
35 }
36}
各类操作结果如下:
表达式 | 结果 |
---|---|
.store | store 内的所有数据 |
.store.bicycle.price | store 内 bicycle 的价格 |
{color: .store.bicycle.color} | {"color": "red"} |
.store.book[2] | store 内的第3个book对象 |
.store.book[0:2] | store 内的前两本书 |
.store.book[] | select(.price < 10) | store 内所有价格小于10的book |
.store.book[].author | store 内的所有书的作者 |
jq 是一个功能强大的、用于解析 json 数据的工具,关于 jq 的更多用法,您可参考