功能说明

transformer 插件可以对请求/响应头、请求查询参数、请求/响应体参数进行转换,支持的转换操作类型包括删除、重命名、更新、添加、追加、映射、去重。

运行属性

插件执行阶段:认证阶段 插件执行优先级:410

配置字段

名称数据类型填写要求默认值描述
reqRulesstring选填,reqRules和respRules至少填一个-请求转换器配置,指定转换操作类型以及请求头、请求查询参数、请求体的转换规则
respRulesstring选填,reqRules和respRules至少填一个-响应转换器配置,指定转换操作类型以及响应头、响应体的转换规则

reqRulesrespRules中每一项的配置字段说明如下:

名称数据类型填写要求默认值描述
operatestring必填,可选值为 remove, rename, replace, add, append, map, dedupe-指定转换操作类型,支持的操作类型有删除 (remove)、重命名 (rename)、更新 (replace)、添加 (add)、追加 (append)、映射 (map)、去重 (dedupe),当存在多项不同类型的转换规则时,按照上述操作类型顺序依次执行
mapSourcestring选填,可选值为headers, querys,body-仅在operate为map时有效。指定映射来源,若不填该字段,则默认映射来源为自身
headersarray of object选填-指定请求/响应头转换规则
querysarray of object选填-指定请求查询参数转换规则
bodyarray of object选填-指定请求/响应体参数转换规则,请求体转换允许 content-type 为 application/json, application/x-www-form-urlencoded, multipart/form-data;响应体转换仅允许 content-type 为 application/json

headers, querys, body中每一项的配置字段说明如下:

名称数据类型填写要求默认值描述
keystring选填-在operate为remove时使用,用法详见转换操作类型
oldKeystring选填-在operate为rename时使用,用法详见转换操作类型
newKeystring选填-在operate为rename时使用,用法详见转换操作类型
keystring选填-在operate为replace时使用,用法详见转换操作类型
newValuestring选填-在operate为replace时使用,用法详见转换操作类型
keystring选填-在operate为add时使用,用法详见转换操作类型
valuestring选填-在operate为add时使用,用法详见转换操作类型
keystring选填-在operate为append时使用,用法详见转换操作类型
appendValuestring选填-在operate为append时使用,用法详见转换操作类型
fromKeystring选填-在operate为map时使用,用法详见转换操作类型
toKeystring选填-在operate为map时使用,用法详见转换操作类型
keystring选填-在operate为dedupe时使用,用法详见转换操作类型
strategystring选填-在operate为dedupe时使用,用法详见转换操作类型
value_typestring选填,可选值为 object, boolean, number, stringstringcontent-type: application/json时,该字段指定请求/响应体参数的值类型
host_patternstring选填-指定请求主机名匹配规则,当转换操作类型为 replace, add, append 时有效
path_patternstring选填-指定请求路径匹配规则,当转换操作类型为 replace, add, append 时有效

注意:

  • request transformer 支持以下转换对象:请求头部、请求查询参数、请求体(application/json, application/x-www-form-urlencoded, multipart/form-data)
  • response transformer 支持以下转换对象:响应头部、响应体(application/json)
  • 插件支持双向转换能力,即单个插件能够完成对请求和响应都做转换
  • 转换操作类型的执行顺序,为配置文件中编写的顺序,如:remove → rename → replace → add → append → map → dedupe或者dedupe → map → append → add → replace → rename → remove等
  • 当转换对象为 headers 时, key 不区分大小写;当为 headers 且为 rename, map 操作时,value 也不区分大小写(因为此时该字段具有 key 含义);而 querys 和 body 的 key, value 字段均区分大小写
  • value_type 仅对 content-type 为 application/json 的请求/响应体有效
  • host_patternpath_pathern 支持 RE2 语法,仅对 replace, add, append 操作有效,且在一项转换规则中两者只能选填其一,若均填写,则 host_pattern 生效,而 path_pattern 失效

转换操作类型

操作类型key 字段含义value 字段含义描述
删除 remove目标 key无需设置若存在指定的 key,则删除;否则无操作
重命名 rename目标 oldKey新的 key 名称 newKey若存在指定的 oldKey:value,则将其键名重命名为 newKey,得到 newKey:value;否则无操作
更新 replace目标 key新的 value 值 newValue若存在指定的 key:value,则将其 value 更新为 newValue,得到 key:newValue;否则无操作
添加 add添加的 key添加的 value若不存在指定的 key:value,则添加;否则无操作
追加 append目标 key追加的 value值 appendValue若存在指定的 key:value,则追加 appendValue 得到 key:[value…, appendValue];否则相当于执行 add 操作,得到 key:appendValue
映射 map映射来源 fromKey映射目标 toKey若存在指定的 fromKey:fromValue,则将其值 fromValue 映射给 toKey 的值,得到 toKey:fromValue,同时保留 fromKey:fromValue(注:若 toKey 已存在则其值会被覆盖);否则无操作
去重 dedupe目标 key指定去重策略 strategystrategy 可选值为:
RETAIN_UNIQUE: 按顺序保留所有唯一值,如 k1:[v1,v2,v3,v3,v2,v1],去重后得到 k1:[v1,v2,v3]
RETAIN_LAST: 保留最后一个值,如 k1:[v1,v2,v3],去重后得到 k1:v3
RETAIN_FIRST (default): 保留第一个值,如 k1:[v1,v2,v3],去重后得到 k1:v1
(注:若去重后只剩下一个元素 v1 时,键值对变为 k1:v1, 而不是 k1:[v1]

配置示例

实现基于Body参数路由

配置示例:

  1. reqRules:
  2. - operate: map
  3. headers:
  4. - fromKey: userId
  5. toKey: x-user-id
  6. mapSource: body

此规则将请求body中的userId解析出后,设置到请求Headerx-user-id中,这样就可以基于Higress请求Header匹配路由的能力来实现基于Body参数的路由了。

此配置同时支持application/jsonapplication/x-www-form-urlencoded两种类型的请求Body。

举例来说:

对于application/json类型的body

  1. curl localhost -d ‘{“userId”:12, userName”:”johnlanni”}’ -H content-type:application/json

将从json中提取出userId字段的值,设置到x-user-id中,后端服务收到的请求头将增加:x-usr-id: 12

因为在插件新增这个Header后,网关将重新计算路由,所以可以实现网关路由配置根据这个请求头来匹配路由到特定的目标服务。

对于application/x-www-form-urlencoded类型的body

  1. curl localhost -d userId=12&userName=johnlanni

将从k1=v1&k2=v2这样的表单格式中提取出userId字段的值,设置到x-user-id中,后端服务收到的请求头将增加:x-usr-id: 12

因为在插件新增这个Header后,网关将重新计算路由,所以可以实现网关路由配置根据这个请求头来匹配路由到特定的目标服务。

json path 支持

可以根据 GJSON Path 语法,从复杂的 json 中提取出字段。

比较常用的操作举例,对于以下 json:

  1. {
  2. name”: {“first”: Tom”, last”: Anderson”},
  3. age”:37,
  4. children”: [“Sara”,”Alex”,”Jack”],
  5. fav.movie”: Deer Hunter”,
  6. friends”: [
  7. {“first”: Dale”, last”: Murphy”, age”: 44, nets”: [“ig”, fb”, tw”]},
  8. {“first”: Roger”, last”: Craig”, age”: 68, nets”: [“fb”, tw”]},
  9. {“first”: Jane”, last”: Murphy”, age”: 47, nets”: [“ig”, tw”]}
  10. ]
  11. }

可以实现这样的提取:

  1. name.last Anderson
  2. name.first Tom
  3. age 37
  4. children [“Sara”,”Alex”,”Jack”]
  5. children.0 Sara
  6. children.1 Alex
  7. friends.1 {“first”: Roger”, last”: Craig”, age”: 68}
  8. friends.1.first Roger

现在如果想从上面这个 json 格式的 body 中提取出 friends 中第二项的 first 字段,来设置到 Header x-first-name 中,同时抽取 last 字段,来设置到 Header x-last-name 中,则可以使用这份插件配置:

  1. reqRules:
  2. - operate: map
  3. headers:
  4. - fromKey: friends.1.first
  5. toKey: x-first-name
  6. - fromKey: friends.1.last
  7. toKey: x-last-name
  8. mapSource: body

Request Transformer

转换请求头部

  1. reqRules:
  2. - operate: remove
  3. headers:
  4. - key: X-remove
  5. - operate: rename
  6. headers:
  7. - oldKey: X-not-renamed
  8. newKey: X-renamed
  9. - operate: replace
  10. headers:
  11. - key: X-replace
  12. newValue: replaced
  13. - operate: add
  14. headers:
  15. - key: X-add-append
  16. value: host-$1
  17. host_pattern: ^(.).com$
  18. - operate: append
  19. headers:
  20. - key: X-add-append
  21. appendValue: path-$1
  22. path_pattern: ^.?\/(\w+)[\?]{0,1}.*$
  23. - operate: map
  24. headers:
  25. - fromKey: X-add-append
  26. toKey: X-map
  27. - operate: dedupe
  28. headers:
  29. - key: X-dedupe-first
  30. strategy: RETAIN_FIRST
  31. - key: X-dedupe-last
  32. strategy: RETAIN_LAST
  33. - key: X-dedupe-unique
  34. strategy: RETAIN_UNIQUE

发送请求

  1. $ curl -v console.higress.io/get -H host: foo.bar.com \
  2. -H X-remove: exist -H X-not-renamed:test -H X-replace:not-replaced \
  3. -H X-dedupe-first:1 -H X-dedupe-first:2 -H X-dedupe-first:3 \
  4. -H X-dedupe-last:a -H X-dedupe-last:b -H X-dedupe-last:c \
  5. -H X-dedupe-unique:1 -H X-dedupe-unique:2 -H X-dedupe-unique:3 \
  6. -H X-dedupe-unique:3 -H X-dedupe-unique:2 -H X-dedupe-unique:1
  7. # httpbin 响应结果
  8. {
  9. args”: {},
  10. headers”: {
  11. X-Add-Append”: host-foo.bar,path-get”,
  12. X-Dedupe-First”: 1”,
  13. X-Dedupe-Last”: c”,
  14. X-Dedupe-Unique”: 1,2,3”,
  15. X-Map”: host-foo.bar,path-get”,
  16. X-Renamed”: test”,
  17. X-Replace”: replaced
  18. },
  19. }

转换请求查询参数

  1. reqRules:
  2. - operate: remove
  3. querys:
  4. - key: k1
  5. - operate: rename
  6. querys:
  7. - oldKey: k2
  8. newKey: k2-new
  9. - operate: replace
  10. querys:
  11. - key: k2-new
  12. newValue: v2-new
  13. - operate: add
  14. querys:
  15. - key: k3
  16. value: v31-$1
  17. path_pattern: ^.?\/(\w+)[\?]{0,1}.$
  18. - operate: append
  19. querys:
  20. - key: k3
  21. appendValue: v32
  22. - operate: map
  23. querys:
  24. - fromKey: k3
  25. toKey: k4
  26. - operate: dedupe
  27. querys:
  28. - key: k4
  29. strategy: RETAIN_FIRST

发送请求

  1. $ curl -v console.higress.io/get?k1=v11&k1=v12&k2=v2
  2. # httpbin 响应结果
  3. {
  4. args”: {
  5. k2-new”: v2-new”,
  6. k3”: [
  7. v31-get”,
  8. v32
  9. ],
  10. k4”: v31-get
  11. },
  12. }

转换请求体

  1. reqRules:
  2. - operate: remove
  3. body:
  4. - key: a1
  5. - operate: rename
  6. body:
  7. - oldKey: a2
  8. newKey: a2-new
  9. - operate: replace
  10. body:
  11. - key: a3
  12. newValue: t3-new
  13. value_type: string
  14. - operate: add
  15. body:
  16. - key: a1-new
  17. value: t1-new
  18. value_type: string
  19. - operate: append
  20. body:
  21. - key: a1-new
  22. appendValue: t1-$1-append
  23. value_type: string
  24. host_pattern: ^(.*).com$
  25. - operate: map
  26. body:
  27. - fromKey: a1-new
  28. toKey: a4
  29. - operate: dedupe
  30. body:
  31. - key: a4
  32. strategy: RETAIN_FIRST

发送请求:

1. Content-Type: application/json

  1. $ curl -v -x POST console.higress.io/post -H host: foo.bar.com \
  2. -H Content-Type: application/json -d ‘{“a1”:”t1”,”a2”:”t2”,”a3”:”t3”}’
  3. # httpbin 响应结果
  4. {
  5. headers”: {
  6. Content-Type”: application/json”,
  7. },
  8. json”: {
  9. a1-new”: [
  10. t1-new”,
  11. t1-foo.bar-append
  12. ],
  13. a2-new”: t2”,
  14. a3”: t3-new”,
  15. a4”: t1-new
  16. },
  17. }

2. Content-Type: application/x-www-form-urlencoded

  1. $ curl -v -X POST console.higress.io/post -H host: foo.bar.com \
  2. -d a1=t1&a2=t2&a3=t3
  3. # httpbin 响应结果
  4. {
  5. form”: {
  6. a1-new”: [
  7. t1-new”,
  8. t1-foo.bar-append
  9. ],
  10. a2-new”: t2”,
  11. a3”: t3-new”,
  12. a4”: t1-new
  13. },
  14. headers”: {
  15. Content-Type”: application/x-www-form-urlencoded”,
  16. },
  17. }

3. Content-Type: multipart/form-data

  1. $ curl -v -X POST console.higress.io/post -H host: foo.bar.com \
  2. -F a1=t1 -F a2=t2 -F a3=t3
  3. # httpbin 响应结果
  4. {
  5. form”: {
  6. a1-new”: [
  7. t1-new”,
  8. t1-foo.bar-append
  9. ],
  10. a2-new”: t2”,
  11. a3”: t3-new”,
  12. a4”: t1-new
  13. },
  14. headers”: {
  15. Content-Type”: multipart/form-data; boundary=————————————1118b3fab5afbc4e”,
  16. },
  17. }

Response Transformer

与 Request Transformer 类似,在此仅说明转换 JSON 形式的请求/响应体时的注意事项:

key 嵌套 .

1.通常情况下,指定的 key 中含有 . 表示嵌套含义,如下:

  1. respRules:
  2. - operate: add
  3. body:
  4. - key: foo.bar
  5. value: value
  1. $ curl -v console.higress.io/get
  2. # httpbin 响应结果
  3. {
  4. foo”: {
  5. bar”: value
  6. },
  7. }

2.当使用 \. 对 key 中的 . 进行转义后,表示非嵌套含义,如下:

当使用双引号括住字符串时使用 \\. 进行转义

  1. respRules:
  2. - operate: add
  3. body:
  4. - key: foo.bar
  5. value: value
  1. $ curl -v console.higress.io/get
  2. # httpbin 响应结果
  3. {
  4. foo.bar”: value”,
  5. }

访问数组元素 .index

可以通过数组下标 `array.index 访问数组元素,下标从 0 开始:

  1. {
  2. users”: [
  3. {
  4. 123”: { name”: zhangsan”, age”: 18 }
  5. },
  6. {
  7. 456”: { name”: lisi”, age”: 19 }
  8. }
  9. ]
  10. }

1.移除 user 第一个元素:

  1. reqRules:
  2. - operate: remove
  3. body:
  4. - key: users.0
  1. $ curl -v -X POST console.higress.io/post \
  2. -H Content-Type: application/json \
  3. -d ‘{“users”:[{“123”:{“name”:”zhangsan”}},{“456”:{“name”:”lisi”}}]}’
  4. # httpbin 响应结果
  5. {
  6. json”: {
  7. users”: [
  8. {
  9. 456”: {
  10. name”: lisi
  11. }
  12. }
  13. ]
  14. },
  15. }

2.将 users 第一个元素的 key 为 123 重命名为 msg:

  1. reqRules:
  2. - operate: rename
  3. body:
  4. - oldKey: users.0.123
  5. newKey: users.0.first
  1. $ curl -v -X POST console.higress.io/post \
  2. -H Content-Type: application/json \
  3. -d ‘{“users”:[{“123”:{“name”:”zhangsan”}},{“456”:{“name”:”lisi”}}]}’
  4. # httpbin 响应结果
  5. {
  6. json”: {
  7. users”: [
  8. {
  9. msg”: {
  10. name”: zhangsan
  11. }
  12. },
  13. {
  14. 456”: {
  15. name”: lisi
  16. }
  17. }
  18. ]
  19. },
  20. }

遍历数组元素 .#

可以使用 array.# 对数组进行遍历操作:

❗️该操作目前只能用在 replace 上,请勿在其他转换中尝试该操作,以免造成无法预知的结果

  1. {
  2. users”: [
  3. {
  4. name”: zhangsan”,
  5. age”: 18
  6. },
  7. {
  8. name”: lisi”,
  9. age”: 19
  10. }
  11. ]
  12. }
  1. reqRules:
  2. - operate: replace
  3. body:
  4. - key: users.#.age
  5. newValue: 20
  1. $ curl -v -X POST console.higress.io/post \
  2. -H Content-Type: application/json \
  3. -d ‘{“users”:[{“name”:”zhangsan”,”age”:18},{“name”:”lisi”,”age”:19}]}’
  4. # httpbin 响应结果
  5. {
  6. json”: {
  7. users”: [
  8. {
  9. age”: 20”,
  10. name”: zhangsan
  11. },
  12. {
  13. age”: 20”,
  14. name”: lisi
  15. }
  16. ]
  17. },
  18. }