Function Description

The transformer plugin can transform request/response headers, request query parameters, and request/response body parameters. Supported transformation operation types include deletion, renaming, updating, adding, appending, mapping, and deduplication.

Execution Attributes

Plugin execution phase: authentication phase
Plugin execution priority: 410

Configuration Fields

NameData TypeFill RequirementDefault ValueDescription
reqRulesstringOptional, at least one of reqRules or respRules must be filled-Request transformer configuration, specifying the transformation operation type and rules for transforming request headers, request query parameters, and request body
respRulesstringOptional, at least one of reqRules or respRules must be filled-Response transformer configuration, specifying the transformation operation type and rules for transforming response headers and response body

The configuration fields for each item in reqRules and respRules are as follows:

NameData TypeFill RequirementDefault ValueDescription
operatestringRequired, optional values are remove, rename, replace, add, append, map, dedupe-Specifies the transformation operation type. Supported operation types include remove (remove), rename (rename), replace (replace), add (add), append (append), map (map), dedupe (dedupe). When there are multiple transformation rules of different types, they are executed in the order of the above operation types.
mapSourcestringOptional, optional values are headers, querys, body-Valid only when operate is map. Specifies the mapping source. If this field is not filled, the default mapping source is itself.
headersarray of objectOptional-Specifies transformation rules for request/response headers.
querysarray of objectOptional-Specifies transformation rules for request query parameters.
bodyarray of objectOptional-Specifies transformation rules for request/response body parameters. Request body transformations allow content-types of application/json, application/x-www-form-urlencoded, and multipart/form-data while response body transformations only allow content-type of application/json.

The configuration fields for each item in headers, querys, body are as follows:

NameData TypeFill RequirementDefault ValueDescription
keystringOptional-Used when operate is remove, see Transformation Operation Types for details.
oldKeystringOptional-Used when operate is rename, see Transformation Operation Types for details.
newKeystringOptional-Used when operate is rename, see Transformation Operation Types for details.
keystringOptional-Used when operate is replace, see Transformation Operation Types for details.
newValuestringOptional-Used when operate is replace, see Transformation Operation Types for details.
keystringOptional-Used when operate is add, see Transformation Operation Types for details.
valuestringOptional-Used when operate is add, see Transformation Operation Types for details.
keystringOptional-Used when operate is append, see Transformation Operation Types for details.
appendValuestringOptional-Used when operate is append, see Transformation Operation Types for details.
fromKeystringOptional-Used when operate is map, see Transformation Operation Types for details.
toKeystringOptional-Used when operate is map, see Transformation Operation Types for details.
keystringOptional-Used when operate is dedupe, see Transformation Operation Types for details.
strategystringOptional-Used when operate is dedupe, see Transformation Operation Types for details.
value_typestringOptional, optional values are object, boolean, number, stringstringWhen content-type: application/json, this field specifies the value type of request/response body parameters.
host_patternstringOptional-Specifies the request hostname matching rule. Valid when transformation operation type is replace, add, append.
path_patternstringOptional-Specifies the request path matching rule. Valid when transformation operation type is replace, add, append.

Note:

  • request transformer supports the following transformation objects: request headers, request query parameters, request body (application/json, application/x-www-form-urlencoded, multipart/form-data).
  • response transformer supports the following transformation objects: response headers, response body (application/json).
  • The plugin supports bidirectional conversion capability, meaning that a single plugin can perform transformations on both requests and responses.
  • The execution order of transformation operation types is the order written in the configuration file, e.g., remove → rename → replace → add → append → map → dedupe or dedupe → map → append → add → replace → rename → remove.
  • When the transformation object is headers, key is case-insensitive. When headers are operated and are rename or map, value is also case-insensitive (as this field has a key meaning). However, key and value fields in querys and body are case-sensitive.
  • value_type is only effective for content type application/json for request/response bodies.
  • host_pattern and path_pattern support RE2 syntax, valid only for replace, add, append operations. In a transformation rule, only one of the two can be optionally filled. If both are filled, then host_pattern takes effect while path_pattern becomes ineffective.

Transformation Operation Types

Operation TypeKey Field MeaningValue Field MeaningDescription
Remove removeTarget keyNot requiredIf the specified key exists, delete it; otherwise, no operation
Rename renameTarget oldKeyNew key name newKeyIf the specified oldKey:value exists, rename its key to newKey, resulting in newKey:value; otherwise, no operation
Replace replaceTarget keyNew value newValueIf the specified key:value exists, update its value to newValue, resulting in key:newValue; otherwise, no operation
Add addAdded keyAdded valueIf the specified key:value does not exist, add it; otherwise, no operation
Append appendTarget keyAppending value appendValueIf the specified key:value exists, append appendValue to get key:[value…, appendValue]; otherwise, it is equivalent to performing add operation, resulting in key:appendValue.
Map mapMapping source fromKeyMapping target toKeyIf the specified fromKey:fromValue exists, map its value fromValue to the value of toKey, resulting in toKey:fromValue, while retaining fromKey:fromValue (note: if toKey already exists, its value will be overwritten); otherwise, no operation.
Deduplicate dedupeTarget keySpecified deduplication strategy strategystrategy optional values include:
RETAIN_UNIQUE: Retain all unique values in order, e.g., k1:[v1,v2,v3,v3,v2,v1], deduplication results in k1:[v1,v2,v3].
RETAIN_LAST: Retain the last value, e.g., k1:[v1,v2,v3], deduplication results in k1:v3.
RETAIN_FIRST (default): Retain the first value, e.g., k1:[v1,v2,v3], deduplication results in k1:v1.
(Note: When deduplication results in only one element v1, the key-value pair becomes k1:v1, not k1:[v1].)

Configuration Example

Implement Routing Based on Body Parameters

Configuration example:

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

This rule extracts the userId from the request body and sets it in the request header x-user-id. This allows routing based on body parameters using Higress’s ability to match on request headers.

This configuration supports both application/json and application/x-www-form-urlencoded types of request bodies.

For example: For application/json type body

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

The value of the userId field will be extracted from the JSON and set to x-user-id. The backend service will receive a request header with: x-user-id: 12.

After the plugin adds this header, the gateway will recalculate the routes, allowing the routing configuration to match the specific target service based on this request header.

For application/x-www-form-urlencoded type body

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

The value of the userId field will be extracted from the form format k1=v1&k2=v2 and set to x-user-id. The backend service will receive a request header with: x-user-id: 12.

After the plugin adds this header, the gateway will recalculate the routes, allowing the routing configuration to match the specific target service based on this request header.

JSON Path Support

You can extract fields from complex JSON according to GJSON Path syntax.

Common operations include, for the following 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. }

You can achieve such extractions:

  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

Now, if you want to extract the first field from the second item in friends from the above JSON formatted body and set it to the header x-first-name, while also extracting the last field to set it to the header x-last-name, you can use this plugin configuration:

  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

Transforming Request Headers

  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

Send Request

  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 response result
  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. }

Transforming Request Query Parameters

  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

Send Request

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

Transforming Request Body

  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

Send Requests: 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 response result
  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 response result
  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 response result
  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

Similar to Request Transformer, this only describes the precautions for transforming JSON-formatted request/response bodies:

Key Nesting .

  1. In general, a key containing . indicates a nested meaning, as follows:
  1. respRules:
  2. - operate: add
  3. body:
  4. - key: foo.bar
  5. value: value
  1. $ curl -v console.higress.io/get
  2. # httpbin response result
  3. {
  4. foo”: {
  5. bar”: value
  6. },
  7. }
  1. When using \. to escape . in the key, it indicates a non-nested meaning, as follows:

When enclosing a string with double quotes, use \\. for escaping

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

Accessing Array Elements .index

You can access array elements by their index array.index, where the index starts from 0:

  1. {
  2. users”: [
  3. {
  4. 123”: { name”: zhangsan”, age”: 18 }
  5. },
  6. {
  7. 456”: { name”: lisi”, age”: 19 }
  8. }
  9. ]
  10. }
  1. Remove the first element of 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 response result
  5. {
  6. json”: {
  7. users”: [
  8. {
  9. 456”: {
  10. name”: lisi
  11. }
  12. }
  13. ]
  14. },
  15. }
  1. Rename the key 123 of the first element of users to 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 response result
  5. {
  6. json”: {
  7. users”: [
  8. {
  9. msg”: {
  10. name”: zhangsan
  11. }
  12. },
  13. {
  14. 456”: {
  15. name”: lisi
  16. }
  17. }
  18. ]
  19. },
  20. }

Iterating Array Elements .#

You can use array.# to iterate over an array:

❗️This operation can only be used in replace, do not attempt this operation in other transformations to avoid unpredictable results

  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 response result
  5. {
  6. json”: {
  7. users”: [
  8. {
  9. age”: 20”,
  10. name”: zhangsan
  11. },
  12. {
  13. age”: 20”,
  14. name”: lisi
  15. }
  16. ]
  17. },
  18. }