Skip to main content
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:

Mustache

Simple syntax, sections for loops and conditionals. Works on all JVM versions.

Velocity

Apache Velocity — richer logic including loops, math, and JSON/XML parsing tools. Works on all JVM versions.

JavaScript

Uses the Nashorn engine. Full ES6 support on Java 9–14. Deprecated in Java 11, removed in Java 15+.
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.

Request model variables

Every template has access to a request object with the following fields:
FieldDescription
request.methodHTTP method (e.g. GET)
request.pathRequest path (e.g. /some/path)
request.pathParametersMap of path parameter values (multi-value)
request.queryStringParametersMap of query parameter values (multi-value)
request.headersMap of header values (multi-value)
request.cookiesMap of cookie values (single-value)
request.bodyRequest body as an object
request.bodyAsStringRequest body as a plain string
request.securetrue for HTTPS
request.keepAlivetrue if the client requested keep-alive
request.remoteAddressClient IP address
Multi-value fields (headers, pathParameters, queryStringParameters) hold arrays. Access the first value with an index ([0] or .0).

Syntax by engine

FieldMustacheVelocityJavaScript
method{{ request.method }}$!request.methodrequest.method
path{{ request.path }}$!request.pathrequest.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.bodyrequest.body

Dynamic built-in variables

All engines also expose these variables. Each call produces a fresh value:
VariableDescription
now_iso_8601Current datetime in ISO 8601 (2011-12-03T10:15:30Z)
now_epochUnix epoch (seconds since Jan 1 1970)
now_rfc_1123Current datetime in RFC 1123 (Tue, 3 Jun 2008 11:05:30 GMT)
uuidRandom UUID string
rand_int_10Random integer 0–9
rand_int_100Random integer 0–99
rand_bytes_1616 random bytes
rand_bytes_3232 random bytes
rand_bytes_6464 random bytes
rand_bytes_128128 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

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.
{
  "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 }}:
{
  "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):
{
  "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 }}:
{
  "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 }}:
{
  "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

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

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

Loops

{
    '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:
#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

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"
    }
}'

JavaScript templates

JavaScript templates use Nashorn and must return a response object.

Basic example

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):
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

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)
    );
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.