Templating language
Learn how to use transformation templates to transform headers and bodies of requests and responses.
About transformation templates
Gloo Gateway transformation templates are powered by v3.4 of the Inja template engine, which is inspired by the popular Jinja templating language in Python. The template lets you transform headers and body information of a request or response based on the header and body properties themselves.
The following YAML file shows the structure of the transformation template and all the attributes that you can configure. To learn more about each attribute, see Template attributes.
transformationTemplate:
headers: {}
headersToAppend: {}
# Only one of body, passthrough, and mergeExtractorsToBody can be specified
body: {}
parseBodyBehavior: {}
ignoreErrorOnParse: bool
extractors: {}
passthrough: {}
mergeExtractorsToBody: {}
dynamicMetadataValues: []
advancedTemplates: bool
escapeCharacters: bool
When writing your templates, you can take advantage of all the core Inja features, such as loops, conditional logic, and functions. In addition, Gloo Gateway comes with custom Inja functions that you can use to transform request and response metadata more easily.
Custom Inja functions
When specifying your transformation template, you can leverage custom Gloo Gateway funtions that can help to extract and transform headers and bodies more easily. These functions are available in the headers
, headersToAppend
, body
, and dynamicMetadataValues
attributes of your transformation template.
Function | Description |
---|---|
base64_encode(string) | Encodes the input string to base64. |
base64_decode(string) | Decodes the input string from base64. For an example, see Decode base64 headers. |
body() | Returns the request/response body. For an example, see Update response body. |
context() | Returns the base JSON context. You can use this context to parse a JSON body that is an array. |
env(env_var_name) | Returns the value of the environment variable with the given name. Note that because the transformation filter is processed in the gateway proxy, the environment variables are returned in the context of the gateway proxy. For an example, see Inject response headers. |
extraction(extractor_name) | Returns the value of the extractor with the given name. This function is required to access extractors when advancedTemplates is set to true . For more information, see advancedTemplates . |
header(header_name) | Returns the value of the header with the given name. For an example, see Change response status. |
raw_string(string) | Returns the input string with escaped characters intact. This function is useful for constructing JSON request or response bodies. For an example, see Inject response headers. |
replace_with_random(string, pattern) | Finds the pattern in the input string and replaces this pattern with a random string. For an example, see Inject response headers. |
request_header(header_name) | Returns the value of the request header with the given name. This function is useful to add the request header values in response transformations. For an example for how to extract a request header value and inject it into a response header, see Inject response headers. |
substring(string, start_pos, substring_len) | Returns a substring of the input string, starting at start_pos and extending for substring_len characters. If no substring_len is provided or substring_len is <= 0 , the substring extends to the end of the input string. For an example, see Decode base64 headers. |
Other common functions
You might use default Inja functions, such as if else
or if exists
. For an example, see Change response status.
Template attributes
Learn more about the template attributes that you can use to transform headers and bodies of requests and responses.
headers
Apply transformation templates to request or response headers. The headers
attribute allows you to specify the name of the resulting header key and applies a transformation template before determining the resulting header value. To transform the header value, you can leverage default and custom Inja functions, static values, or extractors.
headersToAppend
Append values to existing headers. For example, to add multiple values to the same header, use the following transformation template:
transformationTemplate:
headersToAppend:
- key: Set-Cookie
value:
text: 'customcookie2={{ request_header("Host") }}'
- key: Set-Cookie
value:
text: 'customcookie3={{ request_header("Host") }}'
For an example, see Add multiple values to headers.
body
Apply transformation templates to request or response bodies. The body
attribute allows you to specify the structure of the body that you want to return. For example, you can replace values in the body, extract values from headers and add them to the body, or return a static body.
Note that you cannot set the mergeExtractorsToBody
or passthrough
attributes when body
is set.
parseBodyBehavior
Select how you want Gloo Gateway to parse the request or response body.
ParseAsJson
: Instruct Gloo Gateway to parse the body as a JSON. Note that this is the default behavior in Gloo Gateway. IfparseBodyBehavior
is not set, the body is automatically parsed as a JSON. If Gloo Gateway fails to parse the body as a JSON, a 400 Bad Request HTTP error is returned.transformationTemplate: parseBodyBehavior: ParseAsJson
DontParse
: Buffer the body as plain text, but do not parse it. This is useful for bodies that are not formatted as a JSON. Note that some of the templating features are not available when treating the body as plain text. To skip buffering and parsing of the body completely, see thepassthrough
setting.transformationTemplate: parseBodyBehavior: DontParse
ignoreErrorOnParse
Set this attribute to true
if you want Gloo Gateway to parse the body as a JSON, but to not return an error if the body is not formatted as valid JSON.
transformationTemplate:
parseBodyBehavior: ParseAsJson
ignoreErrorOnParse: true
passthrough
Set this attribute if you want Gloo Gateway to not parse or buffer the body. This option is useful if you do not want to transform or extract information from the request or response body, such as in cases where the payload is large.
transformationTemplate:
passthrough: {}
Note that you cannot set the body
or mergeExtractorsToBody
attributes when passthrough is enabled.
extractors
Use extractors to extract specific information from a header or the body that is sent in a request or response. You can later reference an extractor when injecting headers or transforming the request or response body.
Each extractor must use a regular expression (regex) to define which information you want to extract from the source. If the regex uses capturing groups, you can select the group match that you want to extract by using a subgroup
attribute.
The regex
attribute is required when specifying an extraction, even if you want to capture the entire header or body value. In such cases, provide a catch-all regex pattern, such as '.*'
. If no regex is specified, the extractor silently fails.
Keep in mind that the regex must always match the entire source, even if you want to extract a subset of the soruce information in a capturing group only. If the regex does not match the entire input, the regex silently fails.
Extract values
Review the following examples to learn how to extract information from a header or body.
Use extractors
You can refer to extractors in the headers
or body
transformation template attribute to transform a header or body.
For example, to access the value of the foo
extractor when transforming a header, use the following syntax:
extractors:
# The name of the extractor
foo:
# The extractor uses the :path pseudo header as the source, which contains the request/response path
header: ':path'
# Use a nested capturing group to extract the foo query parameter
regex: '(.*foo=([^&]*).*)'
# Select the second group match, which contains the value of the foo query parameter
subgroup: 2
header:
x-foo:
text: "{{ foo }}"'
Similarly, to refer to it when transforming the body, use the following syntax:
extractors:
# The name of the extractor
foo:
# The extractor uses the :path pseudo header as the source, which contains the request/response path
header: ':path'
# Use a nested capturing group to extract the foo query parameter
regex: '(.*foo=([^&]*).*)'
# Select the second group match, which contains the value of the foo query parameter
subgroup: 2
body:
text: 'This is the foo value: {{ foo }}'
To merge extractors to an existing body, you can use the mergeExtractorsToBody
transformation template attribute. For more information, see mergeExtractorsToBody
.
If advancedTemplates
is set to true
, you must refer to an extractor by using the extraction
Inja function, such as {{ extraction(my-extractor)}}
.
Extractor modes
Gloo Gateway provides predefined extractor modes that you can use to transform the extracted information more easily.
mergeExtractorsToBody
Merge all the extractors that you defined in the transformation template to the body. The place where the extractor is injected into the body is determined by the extractor name. For example, to nest values, you use a name with dot notation, such as root.child
.
The following example defines two extractors:
path
: This exactractor captures the:path
pseudo header value and adds it to thepath
attribute. Because thepath
attribute does not use dot notation, it is added as a root element to the body.host.name
: This extractor captures the value of thehost
header and adds it to thehost.name
attribute. Because this attribute uses dot notation, it is added as a nested element in the body.
transformationTemplate:
mergeExtractorsToBody: {}
extractors:
path:
header: ':path'
regex: '.*'
# The name of this attribute determines where the value will be nested in the body
host.name:
header: 'host'
regex: '.*'
The resulting body looks similar to the following:
{
"path": "/the/request/path",
"host": {
"name": "value of the 'host' header"
}
}
For an example, see Add headers to body.
Note that you cannot set the body
or passthrough
attributes when mergeExtractorsToBody
is enabled.
dynamicMetadataValues
Use this attribute to define an Envoy Dynamic Metadata entry. This metadata can be used by other filters in the filter chain to implement custom behavior.
As an example, the following configuration creates a dynamic metadata entry in the com.example
namespace with the key foo
and the value of the foo
header.
dynamicMetadataValues:
- metadataNamespace: "com.example"
key: 'foo'
value:
text: '{{ header("foo") }}'
Setting the metadataNamespace
is optional. If not set, it defaults to the namespace of the Gloo Gateway transformation filter name, such as io.solo.transformation
.
A common use case for using this attribute is to include custom data in your access logs. For an example, see Enrich access logs.
advancedTemplates
This attribute determines which notation Gloo Gateway uses when accessing elements in JSON structures. If set to true
, Gloo Gateway expects JSON pointer notation (time/start
) instead of dot notation (time.start
). The default value is false
.
transformationTemplate:
parseBodyBehavior: ParseAsJson
advancedTemplates: false
If set to true
, you must use the extraction
function to access extractors in template strings, such as {{ extraction("myExtractor") }}
. If set to false
(default), you must reference extractors in template strings by name only, such as {{ myExtractor }}
.
escapeCharacters
Set to true
to instruct Inja to preserve escaped characters in strings. This option is useful when using context from the request or response body to construct new JSON bodies.
transformationTemplate:
parseBodyBehavior: ParseAsJson
escapceCharacters: true