Scripted responses
Read this section to learn how to use scripts to configure Imposter's responses.
You can control Imposter's responses using JavaScript or Groovy scripts. (If you choose Groovy, you can of course write plain Java in your scripts as well).
Example
Here's an example configuration file that uses a script:
# scripted-example-config.yaml
---
plugin: rest
path: "/example-two"
response:
scriptFile: example.groovy
...and here's the corresponding script (example.groovy
):
if (context.request.queryParams.action == 'create') {
respond().withStatusCode(201)
}
We will explain this syntax later, in the ResponseBehaviour object section. For now, it's enough to know that the example above causes the mock server to respond with HTTP status code 201 if the value of the action
parameter in the request is create
.
For example:
HTTP GET http://localhost:8080/example-two?action=create
...
201 Created
Note See this rest plugin example for a simple example.
Another example
Here's a more sophisticated example script:
switch (context.request.queryParams.action) {
case 'create':
// HTTP Status-Code 201: Created.
respond()
.withStatusCode(201)
.skipDefaultBehaviour()
break
case 'fetch':
// use a static response file and the default plugin behaviour
respond().withFile('example-data.json')
break
default:
// default to bad request
respond()
.withStatusCode(400)
.skipDefaultBehaviour()
break
}
In this example, the script causes the mock server to respond with HTTP status codes 200, 201 or 400 depending on the value of the action
parameter in the request.
For example:
HTTP GET http://localhost:8080/example-two?action=fetch
...
HTTP/1.1 200 OK
...
{
"hello": "world"
}
In the case of action=fetch
, the script causes the mock server to use the content of the static file
static-data.json
to serve the response.
And:
HTTP GET http://localhost:8080/example-two?action=foo
...
400 Bad Request
In the default case, the script causes the mock server to return an HTTP 400 response, as shown above.
The queryParams
object used in the script is just a map of the request query parameters, so you can use either params.yourParamName
or params['yourParamName']
syntax to access its members.
There are many other script objects you could use in order to decide what to return. For example, your script might use the request method (GET, POST, PUT, DELETE etc.) or other request attributes.
Script objects
The following objects are available to your scripts, to help you determine what action to take.
Object | Description |
---|---|
context |
Parent object for accessing request properties |
config |
The plugin configuration for the current request |
env |
A map of environment variables, such as { "MY_VAR": "abc", "VAR2": "def" } |
logger |
Logger, supporting levels such as info(String) , warn(String) etc. |
For example, if you want to access the directory containing the configuration file, you can use config.dir
.
JavaScript example
console.log("Path to config dir: " + config.dir)
var someFile = config.dir + "/example.txt"
// use someFile...
Groovy example
logger.info("Path to config dir: " + config.dir)
def someFile = new java.io.File(config.dir, "example.txt")
// use someFile...
Context object
The context
object is available to your scripts. It holds things you might like to interrogate, like the request object.
Property | Description | Example |
---|---|---|
request |
The HTTP request. | See Request object. |
Note: Certain plugins will add additional properties to the context
. For example, the hbase
plugin provides a tableName
object, which you can use to determine the HBase table for the request being served.
Request object
The request object is available on the context
. It provides access to request parameters, method, URI etc.
Property | Description | Example |
---|---|---|
path |
The path of the request. | "/example" |
method |
The HTTP method of the request. | "GET" |
pathParams |
A map containing the request path parameters. | { "productCode": "abc", "foo": "bar" } |
queryParams |
A map containing the request query parameters. | { "limit": "10", "foo": "bar" } |
formParams |
A map containing the request form parameters. | { "foo": "bar" } |
uri |
The absolute URI of the request. | "http://example.com?foo=bar&baz=qux" |
headers |
A map containing the request headers. | { "X-Example": "ABC123", "Content-Type": "text/plain" } |
normalisedHeaders |
A map containing the request headers with all keys in lowercase. | { "x-example": "ABC123", "content-type": "text/plain" } |
body |
A string containing the request body. | "Hello world." |
Note: keys are always lowercase in
normalisedHeaders
, regardless of the request header casing. This aids script portability, avoiding case-sensitivity for header keys.
Response object
Your scripts have access to the methods on io.gatehill.imposter.script.MutableResponseBehaviour
.
The response behaviour object provides a number of methods to enable you to control the response:
Method | Plugin(s) | Description |
---|---|---|
withStatusCode(int) |
all | Set the HTTP status code for the response. |
withFile(String) |
all | Respond with the content of a static file. Also see template . |
withContent(String) |
all | Respond with the literal content of a string. Also see template . |
withExampleName(String) |
openapi | Use with the OpenAPI plugin to respond with a particular OpenAPI specification example. |
withHeader(String, String) |
all | Set a response header. |
withEmpty() |
all | Respond with empty content, or no records. |
usingDefaultBehaviour() |
all | Use the plugin's default behaviour to respond. |
skipDefaultBehaviour() |
all | Skip the plugin's default behaviour when responding. |
template() |
all | Treat the response file or data as a template with placeholders. |
continueToNext() |
openapi, rest | Used by interceptors to indicate request processing should continue after the script executes. |
and() |
all | Syntactic sugar to improve readability of respond statements. |
You structure your response behaviours like so:
respond() // ... behaviours go here
For example:
respond().withFile('static-data.json')
Or:
respond()
.withStatusCode(201)
.withHeader("x-custom-header", "somevalue")
Returning data from a script
To return data when using a script, you specify a response file or set the content to a string value.
When using a response file, you can either:
- explicitly call the
withFile(String)
method in your script, or - set the
file
property within theresponse
object in your configuration file, which will be used by default unless you override it.
Here's an example of setting the file from a script:
respond().withFile('some-data.json')
Here's an example using the file
property within the configuration file:
# example-config.yaml
---
plugin: rest
path: "/scripted"
contentType: application/json
response:
scriptFile: example.groovy
file: example-data.json
In this example, the response file example-data.json
will be used, unless the script invokes the
withFile(String)
method with a different filename.
Response templates
Response files can be templated, allowing you to populate placeholders with dynamic data.
Returning raw response data
You can return response data using the withContent(String)
method.
respond().withContent('{ "someKey": "someValue" }')
Raw response content can also be templated, allowing you to populate placeholders with dynamic data.
Setting response headers
You can set response headers using the withHeader(String, String)
method.
respond().withHeader('X-Custom-Header', 'example value')
Returning a specific OpenAPI example
When using the OpenAPI plugin, you can return a specific named example from the specification using the withExampleName(String)
method.
respond().withExampleName('example1')
This selects the example from the OpenAPI examples
section for the API response.
Note See this openapi plugin example for a simple example.
Using stores
You can read and write data in Stores using scripts.
Overriding plugin behaviour
In advanced scenarios you can control the response processing behaviour of the mock plugin you're using.
Skipping plugin default behaviour
In order for the mock server to return the response file in an appropriate format, the plugin must be allowed to process it. This is the default behaviour after your script runs. If you want to override the plugin's behaviour, you can call `skipDefaultBehaviour()` on the response (e.g. if you want to send an error code back).respond()
.withStatusCode(400)
.skipDefaultBehaviour()
The alternative to skipping the default behaviour is `usingDefaultBehaviour()`. Whilst not required, your script can invoke this for readability to indicate that you want the plugin to handle the response file for you.
The following blocks are semantically identical:
respond()
.withFile('static-data.json')
.usingDefaultBehaviour()
and:
respond().withFile('static-data.json')