Mockintosh: HTTP Response Templating (Handlebars & Jinja2)

In this part we will talk about the HTTP response templating in Mockintosh. ​

Places Where Templating Is Possible

​ Templating is possible in various places including status, headers and body of an HTTP response. ​

services:
    - port: 8081
      endpoints:
          - path: /api-call
            response:
                status: "{{ request.queryString.rc }}"
                headers:
                    content-type: "{{ request.headers.accept }}"
                    x-custom-id: "{{ random.int 0 1000 }}"
                body: '{"result": "created", "name": "{{fake.lastname}}" }'

You can refer to external resource files using @ sign.

response:
    body: "@some/path/my_template.json.hbs"

​ Mockintosh loads such files on-demand and renders for each individual request. ​

Template Helpers

There is a long list of helpers that are available in templating. Some of them are: ​ "random helper"

{
    "random_int": { { random.int 1 5 } },
    "random_float": { { random.float 1.0 2.0 3 } },
    "random_alphanum": "{{ random.alphanum 7 }}",
    "random_hex": "{{ random.hex 5 }}",
    "random_uuid": "{{ random.uuid4 }}",
    "random_ascii": "{{ random.ascii 11 }}",
}

"date helper"

{
    "now": "{{ date.date '%Y-%m-%d %H:%M %f' }}",
    "1_week_back": "{{ date.date '%Y-%m-%d %H:%M %f' -604800 }},"
    "1_week_forward": "{{ date.date '%Y-%m-%d %H:%M %f' 604800 }},"
    "1_day_back": "{{ date.date '%Y-%m-%d %H:%M %f' -86400 }},"
    "1_day_forward": "{{ date.date '%Y-%m-%d %H:%M %f' 86400 }},"
    "1_hour_back": "{{ date.date '%Y-%m-%d %H:%M %f' -3600 }},"
    "1_hour_forward": "{{ date.date '%Y-%m-%d %H:%M %f' 3600 }},"
    "1_minute_back": "{{ date.date '%Y-%m-%d %H:%M %f' -60 }},"
    "1_minute_forward": "{{ date.date '%Y-%m-%d %H:%M %f' 60 }},"
}

​ "Faker" ​ Faker generates user variables for mocking purposes, for example, first_name, country, and numerify_args. ​ "Request Object"

{
    "request_method": "{{ request.method }}",
    "request_url": "{{ request.url }}",
    "request_host": "{{ request.host }}",
    "request_host_name": "{{ request.host_name }}",
    "request_protocol": "{{ request.protocol }}",
    "request_remote_ip": "{{ request.remoteIp}}",
}

​ "JSON Path" ​

{
    "message": "Welcome {{ jsonPath request.json '$.name' }} {{ jsonPath request.json '$.surname' }}!",
}

"Escape HTML"

{ { escapeHtml '& < \" >' } }

A More Complete Example

​ Here's a more complete example of templating.

We have an HTTP service with two endpoints:

templatingEngine: Jinja2
services:
    - name: Mock for Service1
      hostname: service1.example.com
      port: 8001
      endpoints:
          - path: "/users"
            method: GET
            response:
                headers:
                    Content-Type: "application/json; charset=UTF-8"
                useTemplating: true
                body: "@templates/users.json.j2"
          - path: "/users/{{ id }}"
            method: GET
            response:
                headers:
                    Content-Type: "application/json; charset=UTF-8"
                useTemplating: true
                body: "@templates/user.json.j2"

​The /users endpoint renders the users.json.j2 template file from the templates directory:

{
  "users": [{% for n in range(100) %}]
    {
      "id": {{ random.int(100000, 999999) }},
      "firstName": "{{ fake.first_name() }}",
      "lastName": "{{ fake.last_name() }}",
      "friends": [{% for n in range(range(5) | random) %}]
        {
          "id": {{ random.int(100000, 999999) }}
        }{ if not loop.last %},{% endif %}
      {% endfor %}]
    }{% if not loop.last %},{% endif %}
  {% endfor %}],
  "total": 10
}

Request GET http://service1.example.com:8001/users to view the rendered text from the users.json.j2 template file:

{
    "id": 839351,
    "firstName": "Katherine",
    "lastName": "Martin",
    "friends": [{ "id": 473788 }],
}

​ The /users/id endpoint renders the "user.json.j2" template file. This template renders a single user with IDs injected from the second segment of the requested path. ​

{
  "users": [{% for n in range(100) %}]
    {
      "id": {{ id }}, # injected ID
      "firstName": "{{ fake.first_name() }}",
      "lastName": "{{ fake.last_name() }}",
      "friends": [{% for n in range(range(5) | random) %}]
        {
          "id": {{ random.int(100000, 999999) }}
        }{ if not loop.last %},{% endif %}
      {% endfor %}]
  "total": 10
}

Request GET http://service1.example.com:8001/users/839351 to view the rendered text.

{
    "id": 839351,
    "firstName": "Katherine",
    "lastName": "Martin",
    "friends": [{ "id": 473788 }, { "id": 331004 }, { "id": 522080 }],
}

Support

You can view these examples in action in this video, and learn more at Mockintosh and UP9. Join our community Slack at up9.slack.com.