Go Templates
Last updated: 5 minutes read.
Tyk’s request and response body transform middleware use the Go template language to parse and modify the provided input.
Go templates are also used by Tyk’s webhook event handler to produce the payload for the HTTP request sent to the target system.
In this section of the documentation, we provide some guidance and a few examples on the use of Go templating with Tyk.
Data format conversion using helper functions
Tyk provides two helper functions to assist with data format translation between JSON and XML:
jsonMarshal
performs JSON style character escaping on an XML field and, for complex objects, serialises them to a JSON string (example)xmlMarshal
performs the equivalent conversion from JSON to XML (example)
When creating these functions within your Go templates, please note:
- the use of
.
in the template refers to the entire input, whereas something like.myField
refers to just themyField
field of the input - the pipe
|
joins together the things either side of it, which is typically input data on the left and a receiving command to process the data on the right, such asjsonMarshal
Hence {{ . | jsonMarshal }}
will pass the entire input to the jsonMarshal
helper function.
Using functions within Go templates
You can define and use functions in the Go templates that are used for body transforms in Tyk. Functions allow you to abstract common template logic for cleaner code and to aid reusability. Breaking the template into functions improves readability of more complex tenplates.
Here is an example where we define a function called myFunction
that accepts one parameter:
{{- define "myFunction" }}
Hello {{.}}!
{{- end}}
We can call that function and pass “world” as the parameter:
{
"message": {{ call . "myFunction" "world"}}
}
The output would be:
{
"message": "Hello world!"
}
We have bundled the Sprig Library (v3) which provides over 70 pre-written functions for transformations to assist the creation of powerful Go templates to transform your API requests.
Additional resources
Here’s a useful blogpost and YouTube tutorial that can help you to learn about using Go templates.
Go templating examples
Here we provide worked examples for both JSON and XML formatted inputs. We also explain examples using the jsonMarshal and xmlMarshal helper functions.
Example JSON transformation template
Imagine you have a published API that accepts the request listed below, but your upstream service requires a few alterations, namely:
- swapping the values of parameters
value1
andvalue2
- renaming the
value_list
totransformed_list
- adding a
user-id
extracted from the session metadata - adding a
client-ip
logging the client IP - adding a
req-type
that logs the value provided in query parametertype
Input
- Session metadata
uid
=user123
- IP address of calling client =
192.0.0.1
- Query parameter
type
=strict
{
"value1": "value-1",
"value2": "value-2",
"value_list": [
"one",
"two",
"three"
]
}
Template
{
"value1": "{{.value2}}",
"value2": "{{.value1}}",
"transformed_list": [
{{range $index, $element := index . "value_list"}}
{{if $index}}, {{end}}
"{{$element}}"
{{end}}
],
"user-id": "{{._tyk_meta.uid}}",
"user-ip": "{{._tyk_context.remote_addr}}",
"req-type": "{{ ._tyk_context.request_data.param.type }}"
}
In this template:
.value1
accesses the “value1” field of the input JSON- we swap value1 and value2
- we use the range function to loop through the “value_list” array
._tyk_meta.uid
injects the “uid” session metadata value._tyk_context.remote_addr
injects the client IP address from the context._tyk_context.request_data.param.type
injects query parameter “type”
Output
{
"value1": "value-2",
"value2": "value-1",
"transformed_list": [
"one",
"two",
"three"
],
"user-id": "user123"
"user-ip": "192.0.0.1"
"req-type": "strict"
}
Example XML transformation template
XML cannot be as easily decoded into strict structures as JSON, so the syntax is a little different when working with an XML document. Here we are performing the reverse translation, starting with XML and converting to JSON.
Input
- Session metadata
uid
=user123
- IP address of calling client =
192.0.0.1
- Query parameter
type
=strict
<?xml version="1.0" encoding="UTF-8"?>
<data>
<body>
<value1>value-1</value1>
<value2>value-2</value2>
<valueList>
<item>one</item>
<item>two</item>
<item>three</item>
</valueList>
</body>
</data>
Template
<?xml version="1.0" encoding="UTF-8"?>
<data>
<body>
<value1>{{ .data.body.value2 }}</value1>
<value2>{{ .data.body.value1 }}</value2>
<transformedList>
{{range $index, $element := .data.body.valueList.item }}
<item>{{$element}}</item>
{{end}}
</transformedList>
<userId>{{ ._tyk_meta.uid }}</userId>
<userIp>{{ ._tyk_context.remote_addr }}</userIp>
<reqType>{{ ._tyk_context.request_data.param.type }}</reqType>
</body>
</data>
In this template:
.data.body.value1
accesses the “value1” field of the input XML- we swap value1 and value2
- we use the range function to loop through the “value_list” array
._tyk_meta.uid
injects the “uid” session metadata value._tyk_context.remote_addr
injects the client IP address from the context._tyk_context.request_data.param.type
injects query parameter “type”
Output
<?xml version="1.0" encoding="UTF-8"?>
<data>
<body>
<value1>value-2</value1>
<value2>value-1</value2>
<transformedList>
<item>one</item>
<item>two</item>
<item>three</item>
</transformedList>
<userId>user123</userId>
<userIp>192.0.0.1</userIp>
<reqType>strict</reqType>
</body>
</data>
XML to JSON conversion using jsonMarshal
The jsonMarshal
function converts XML formatted input into JSON, for example:
Input
<hello>world</hello>
Template
{{ . | jsonMarshal }}
Output
{"hello":"world"}
Note that in this example, Go will step through the entire data structure provided to the template. When used in the Request or Response Body Transform middleware, this would include Context Variables and Session Metadata if provided to the middleware.
JSON to XML conversion using xmlMarshal
The xmlMarshal
function converts JSON formatted input into XML, for example:
Input
{"hello":"world"}
Template
{{ . | xmlMarshal }}
Output
<hello>world</hello>
Note that in this example, Go will step through the entire data structure provided to the template. When used in the Request or Response Body Transform middleware, this would include Context Variables and Session Metadata if provided to the middleware.