> ## Documentation Index
> Fetch the complete documentation index at: https://moeck.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Response Templates

> Generate dynamic responses using Mustache, Velocity, or JavaScript templates.

Instead of a fixed response body, you can use a **response template** to build the response dynamically from the incoming request. MockServer supports three template engines:

<CardGroup cols={3}>
  <Card title="Mustache" icon="mustache">
    Simple syntax, sections for loops and conditionals. Works on all JVM versions.
  </Card>

  <Card title="Velocity" icon="bolt">
    Apache Velocity — richer logic including loops, math, and JSON/XML parsing tools. Works on all JVM versions.
  </Card>

  <Card title="JavaScript" icon="js">
    Uses the Nashorn engine. Full ES6 support on Java 9–14. Deprecated in Java 11, removed in Java 15+.
  </Card>
</CardGroup>

<Warning>
  JavaScript templates require the Nashorn JavaScript engine, which was deprecated in Java 11 and removed in Java 15. Do not use JavaScript templates if you are running MockServer on Java 15 or later.
</Warning>

## Request model variables

Every template has access to a `request` object with the following fields:

| Field                           | Description                                 |
| ------------------------------- | ------------------------------------------- |
| `request.method`                | HTTP method (e.g. `GET`)                    |
| `request.path`                  | Request path (e.g. `/some/path`)            |
| `request.pathParameters`        | Map of path parameter values (multi-value)  |
| `request.queryStringParameters` | Map of query parameter values (multi-value) |
| `request.headers`               | Map of header values (multi-value)          |
| `request.cookies`               | Map of cookie values (single-value)         |
| `request.body`                  | Request body as an object                   |
| `request.bodyAsString`          | Request body as a plain string              |
| `request.secure`                | `true` for HTTPS                            |
| `request.keepAlive`             | `true` if the client requested keep-alive   |
| `request.remoteAddress`         | Client IP address                           |

Multi-value fields (`headers`, `pathParameters`, `queryStringParameters`) hold arrays. Access the first value with an index (`[0]` or `.0`).

### Syntax by engine

| Field              | Mustache                                   | Velocity                                   | JavaScript                               |
| ------------------ | ------------------------------------------ | ------------------------------------------ | ---------------------------------------- |
| method             | `{{ request.method }}`                     | `$!request.method`                         | `request.method`                         |
| path               | `{{ request.path }}`                       | `$!request.path`                           | `request.path`                           |
| first header value | `{{ request.headers.Accept.0 }}`           | `$!request.headers['Accept'][0]`           | `request.headers['Accept'][0]`           |
| first query param  | `{{ request.queryStringParameters.id.0 }}` | `$!request.queryStringParameters['id'][0]` | `request.queryStringParameters['id'][0]` |
| cookie value       | `{{ request.cookies.session }}`            | `$!request.cookies['session']`             | `request.cookies['session']`             |
| body               | `{{ request.body }}`                       | `$!request.body`                           | `request.body`                           |

## Dynamic built-in variables

All engines also expose these variables. Each call produces a fresh value:

| Variable         | Description                                                   |
| ---------------- | ------------------------------------------------------------- |
| `now_iso_8601`   | Current datetime in ISO 8601 (`2011-12-03T10:15:30Z`)         |
| `now_epoch`      | Unix epoch (seconds since Jan 1 1970)                         |
| `now_rfc_1123`   | Current datetime in RFC 1123 (`Tue, 3 Jun 2008 11:05:30 GMT`) |
| `uuid`           | Random UUID string                                            |
| `rand_int_10`    | Random integer 0–9                                            |
| `rand_int_100`   | Random integer 0–99                                           |
| `rand_bytes_16`  | 16 random bytes                                               |
| `rand_bytes_32`  | 32 random bytes                                               |
| `rand_bytes_64`  | 64 random bytes                                               |
| `rand_bytes_128` | 128 random bytes                                              |

Syntax follows the same engine conventions (e.g. `{{ uuid }}` in Mustache, `$!uuid` in Velocity, `uuid` in JavaScript).

***

## Mustache templates

Mustache is the simplest option. Use `{{ variable }}` for substitution and `{{# section }}...{{/ section }}` for loops and conditionals.

### Basic example

```java theme={null}
new ClientAndServer(1080)
    .when(request().withPath("/some/path"))
    .respond(
        template(
            HttpTemplate.TemplateType.MUSTACHE,
            "{\n" +
            "    'statusCode': 200,\n" +
            "    'cookies': {\n" +
            "        'session': '{{ request.headers.Session-Id.0 }}'\n" +
            "    },\n" +
            "    'headers': {\n" +
            "        'Client-User-Agent': [ '{{ request.headers.User-Agent.0 }}' ]\n" +
            "    },\n" +
            "    'body': '{{ request.body }}'\n" +
            "}"
        )
    );
```

### Variables

`{{ request.method }}` prints the method. If the variable is unresolvable, an empty string is returned.

```mustache theme={null}
{
  "statusCode": 200,
  "body": {
    "method": "{{ request.method }}",
    "path": "{{ request.path }}",
    "host": "{{ request.headers.host.0 }}"
  }
}
```

### Sections (loops, conditionals)

Sections iterate over arrays or act as if-statements. A section starts with `{{# key }}` and ends with `{{/ key }}`:

```mustache theme={null}
{
  "statusCode": 200,
  "body": "{'headers': '{{# request.headers.entrySet }}{{ key }}={{ value.0 }} {{/ request.headers.entrySet }}'}"
}
```

Use an inverted section `{{^ -first }}` to skip the first item (useful for comma-separated lists):

```mustache theme={null}
{
  "statusCode": 200,
  "body": "{'headers': [{{# request.headers.entrySet }}{{^ -first }}, {{/ -first }}'{{ key }}={{ value.0 }}'{{/ request.headers.entrySet }}]}"
}
```

### JsonPath in Mustache

Extract values from a JSON request body using `{{# jsonPath }}`:

```mustache theme={null}
{
  "statusCode": 200,
  "body": "{'titles': {{# jsonPath }}$.store.book{{/ jsonPath }}[{{# jsonPathResult }}{{^ -first }}, {{/ -first }}'{{ title }}'{{/ jsonPathResult }}], 'bikeColor': '{{# jsonPath }}$.store.bicycle.color{{/ jsonPath }}{{ jsonPathResult }}'}"
}
```

### XPath in Mustache

Extract values from an XML request body using `{{# xPath }}`:

```mustache theme={null}
{
  "statusCode": 200,
  "body": "{'titles': ['{{# xPath }}/store/book/title{{/ xPath }}', '{{# xPath }}//book[2]/title{{/ xPath }}'], 'bikeColor': '{{# xPath }}//bicycle/color{{/ xPath }}'}"
}
```

***

## Velocity templates

Velocity uses `$variable` notation and supports `#if`, `#foreach`, and tool access.

### Basic example

```java theme={null}
new ClientAndServer(1080)
    .when(request().withPath("/some/path"))
    .respond(
        template(
            HttpTemplate.TemplateType.VELOCITY,
            "{\n" +
            "    'statusCode': 200,\n" +
            "    'cookies': {\n" +
            "        'session': '$!request.headers['Session-Id'][0]'\n" +
            "    },\n" +
            "    'headers': {\n" +
            "        'Client-User-Agent': [ '$!request.headers['User-Agent'][0]' ]\n" +
            "    },\n" +
            "    'body': '$!request.body'\n" +
            "}"
        )
    );
```

### Conditionals

```velocity theme={null}
#if($request.method == 'POST' && $request.path == '/somePath')
    {
        'statusCode': 200,
        'body': "{'name': 'value'}"
    }
#else
    {
        'statusCode': 406,
        'body': "$!request.body"
    }
#end
```

### Loops

```velocity theme={null}
{
    'statusCode': 200,
    'body': "{'headers': [#foreach( $value in $request.headers.values() )'$value[0]'#if( $foreach.hasNext ), #end#end]}"
}
```

### Parsing JSON bodies

Use the built-in `$json` tool:

```velocity theme={null}
#set($jsonBody = $json.parse($!request.body))
{
    'statusCode': 200,
    'body': "{'titles': [#foreach( $book in $jsonBody.store.book )'$book.title'#if( $foreach.hasNext ), #end#end]}"
}
```

### Velocity REST API example

<CodeGroup>
  ```bash REST API theme={null}
  curl -v -X PUT "http://localhost:1080/mockserver/expectation" -d '{
      "httpRequest": { "path": "/some/path" },
      "httpResponseTemplate": {
          "template": "{ \"statusCode\": 200, \"cookies\": { \"session\": \"$!request.headers[\"Session-Id\"][0]\" }, \"headers\": { \"Client-User-Agent\": [ \"$!request.headers[\"User-Agent\"][0]\" ] }, \"body\": \"$!request.body\" }",
          "templateType": "VELOCITY"
      }
  }'
  ```
</CodeGroup>

***

## JavaScript templates

JavaScript templates use Nashorn and must return a response object.

### Basic example

```java theme={null}
new ClientAndServer(1080)
    .when(request().withPath("/some/path"))
    .respond(
        template(
            HttpTemplate.TemplateType.JAVASCRIPT,
            "return {\n" +
            "    'statusCode': 200,\n" +
            "    'cookies': {\n" +
            "        'session': request.headers['session-id'][0]\n" +
            "    },\n" +
            "    'headers': {\n" +
            "        'Client-User-Agent': request.headers['User-Agent']\n" +
            "    },\n" +
            "    'body': request.body\n" +
            "};"
        )
    );
```

### Reading the body as a string

Use `request.bodyAsString` when you need the body as a plain string (useful for JSON parsing):

```java theme={null}
template(
    HttpTemplate.TemplateType.JAVASCRIPT,
    "return { statusCode: 200, headers: { Date: [ Date() ] }, body: JSON.stringify({is_active: JSON.parse(request.bodyAsString).is_active, id: '1234', name: 'taras'}) };"
)
```

### Conditional logic and delay

<CodeGroup>
  ```java Java theme={null}
  String template = "" +
      "if (request.method === 'POST' && request.path === '/somePath') {\n" +
      "    return {\n" +
      "        'statusCode': 200,\n" +
      "        'body': JSON.stringify({name: 'value'})\n" +
      "    };\n" +
      "} else {\n" +
      "    return {\n" +
      "        'statusCode': 406,\n" +
      "        'body': request.body\n" +
      "    };\n" +
      "}";

  new MockServerClient("localhost", 1080)
      .when(request().withPath("/some/path"))
      .respond(
          template(HttpTemplate.TemplateType.JAVASCRIPT)
              .withTemplate(template)
              .withDelay(TimeUnit.MINUTES, 2)
      );
  ```

  ```bash REST API theme={null}
  curl -v -X PUT "http://localhost:1080/mockserver/expectation" -d '{
      "httpRequest": {"path": "/some/path"},
      "httpResponseTemplate": {
          "template": "if (request.method === \"POST\" && request.path === \"/some/path\") { return { statusCode: 200, body: JSON.stringify({name: \"value\"}) }; } else { return { statusCode: 406, body: request.body }; }",
          "templateType": "JAVASCRIPT",
          "delay": {"timeUnit": "MINUTES", "value": 2}
      }
  }'
  ```
</CodeGroup>

<Note>
  JavaScript templates support ES6 syntax on Java 9–14 (Nashorn). On Java 15 and later, Nashorn is not available and JavaScript templates will not work. Use Mustache or Velocity instead.
</Note>
