Skip to content

Post processing with templates

Shashank Mehra edited this page Nov 16, 2017 · 3 revisions

For most APIs with json responses, workflow element output is enough. It even allows you to specify the response json structure in a multilevel format:

output:
    body:
        key1:
            subkey1: <%jmes main.subkey1 %>
            subkey2: <%jmes main.subkey2 %>
        key2:
            subkey3: <%jmes main.subkey3 %>
            subkey4: <%jmes main.subkey4 %>
    status_code: <%jmes main.status_code %>

However sometimes a post processing requires passing the data through a template for proper formatting and validation. codon adds a swagger extension to specify which template and template standard to put the data through before returning the response to the client.

x-template

In your main.yml which has the swagger specification for your web service, add the x-template section under path/<path_object>/<method_object>/responses/<response_object>, like:

paths:
  /dogs
    get:
      parameters: ...
      x-workflow: get_dogs
      responses:
        200:
          description: ...
          schema: ...
          x-template:
            location: pets/dogs.tmpl
            standard: django

This specifies that when /dogs is hit with a get request then call get_dogs workflow and send its output object through the template pets/dogs.tmpl which is defined using django format.

The entire output object is available as root object in the template. If your output object looks like:

output:
  body:
    dogs: <%jmes main.dogs %>
    breed_details: <%jmes main.breeds %>
  status_code: 200

The a template could be written with name spec/server/templates/pets/dogs.tmpl as:

{% autoescape off %}
{
  "dogs": [
    {% for dog in body.dogs %}
    "id": "{{ dog.id }}",
    {% with breed=body.breed_details|key:dog.breed_id %}
    "breed_name": {{ breed.name|json }}
    {% endwith %}
    {% endfor %}
  ]
}
{% endautoescape %}

For go-codon, a go implementation for django templates is provided using pongo2. There are a bunch of caveats attached to pongo2, so please check them out.

go-codon uses a fork of pongo2 which has an extra "inbuilt" filters like key (used above). If you want to use the original, you can obviously change the glide dependency file to use the original fork. Pongo2 also allows you to specify custom filters for use in its templates. A json filter can be added by creating a file server/restapi/pongo_filters.go:

package restapi

import (
	"github.com/flosch/pongo2"
	"encoding/json"
)

func init() {
	pongo2.RegisterFilter("json", filterJson)
}

func filterJson(in *pongo2.Value, param *pongo2.Value) (*pongo2.Value, *pongo2.Error) {
	jval, err := json.Marshal(in.Interface())
	if err != nil {
		return nil, &pongo2.Error{
			Sender:    "filter:json",
			OrigError: err,
		}
	}
	return pongo2.AsValue(string(jval)), nil
}

This will register the filter and make it available for use inside the templates.

Clone this wiki locally