Generate Go template from source and target json models

Is there a way to generate Go templates automatically based on source and target json models? What alternatives are there to Go template?

Or maybe a js library that I can use as middleware to map json source to a class and then deserialize to json target?

Hi,

Is there a way to generate Go templates automatically based on source and target json models?

I’m sorry, we don’t provide such a tool. The golang template language is provided to create a way to tranform between formats. Documentation for golang templates it is at template package - text/template - Go Packages. There is a good tutorial introduction at Using Go Templates | Gopher Academy Blog as well. The sprig library is available to enhance the go templates.

What alternatives are there to Go template?

It is possible to use plugins to transform the request and response. Please see the documentation starting at Custom Plugins. However only golang plugins will be comparable in performance to a go template.

Or maybe a js library that I can use as middleware to map json source to a class and then deserialize to json target?

I’m not aware of such a library but please remember that otto, the golang javascript interpreter, is built to support ES5 not ES6 so some off the shelf libraries won’t work with it.

Cheers,
Pete

1 Like

Thanks for you detailed response. I will go with GO template.

It looks like the function first does not work.

 "source": {
          "name": "MV",
          "count": "{{len .data}}",
          "val" : [
          {{ range  $index, $e := first 3 .data }}
          {{ if $index }}, {{end}}
           {"aid": "{{ $e.aid}}", "vid": "{{ $e.vid}}" }
          {{ end }}
          ]
      }

When I remove first n (where n is a number less than total) it works. There are 9 elements.

As an alternative I can check if index is first element but that will be slower in performance, plus more verbose.

  {{ if eq $index 0 }}   
        {"aid": "{{$index}} - {{ $e.aid}} ", "vid": "{{ $e.vid}}" } 
  {{end}}   

Looks like there is no support for a lot of these functions.

Hi,

What version of the gateway are you running? Until version 4.0.1 only sprig v2 functions are supported. After that v3 functions can be used

I should note that sprig functions aren’t evaluated in the dashboard’s API designer. Is that where you’re trying to use them? Unfortunately once sprig functions are used the transform has to be tested by publishing the API to the gateway and testing it via API calls. This is a bit harder but not impossible.

Please let me know the gateway version you’re using and provide a sample of the source and desired result data as well as your current API definition.

Cheers,
Pete

Ok so I am using this version

image: "tykio/tyk-gateway:v3.1.0"

It looks like you have a version 4.2.3

I am going to give this a go.

https://hub.docker.com/r/tykio/tyk-gateway/tags

After going upgrading to 4.2.3 I can use splitList and first but first behaves oddly. It takes one parameter to begin with, which is different from Go Hugo docs, and then it does not work correctly for array of object. It correctlty gets the first object in the array but only renders all the values as a string instead of an object with property and value.

For now I can work with

{{ range $key, $val :=  .data }}
            {{ if eq $key 0 }} 

UPDATE
Is there a way to make http(s) request from the template to get some text data back?

For example I want to resolve this display property based on a parameter.

{{$myText := call_url_func("http://someDomain/" $param).response }}
"display": "{{ $myText }}" 

Hi,

call_url_func is a php function isn’t it? You can’t call php from within a golang template. The only functions available are from sprig

You can call URLs from javascript using the Javascript API when using the javascript middleware.

Cheers,
Pete

1 Like

Hi Pete,

I made up the function name as an example.

So ok middleware makes sense since I would have to make an http(s) call. But before I go down that path (because the golang template was making this process so much easier) is it possible to access data from outside the template file?

What I am thinking is the data I am trying to access is more or less static. I can download and save in a file. The template would then access data from the file. Is this possible? If not, can I load data at the top of the template file but not render?

I am trying to avoid having to write a middleware as that makes making future changes little bit more difficult than the template.

Oh scratch that.

Am I able to access already transformed response body in a post middleware?

Hi,

The capabilities of the different hooks are documented at Request Plugins. You should be able to access the updated body if your plugin is early enough in the call chain, see Request Middleware Chain

But since you’re making progress with golang templates and want more, have you considered moving both the transform and the other data collection to a golang plugin?

That would give you access to the filesystem or any rest API you’d like to call, plus the full resources of golang.

Cheers,
Pete