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).
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)
.skipDefaultBehaviour()
}
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
Tip: The queryParams
object used in the script is just a map of the request parameters, so you can use either params.yourParamName
or params['yourParamName']
syntax to access its members.
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')
.usingDefaultBehaviour()
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.
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.
In order to help you determine what action to take, Imposter makes certain objects available to your scripts.
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...
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.
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.
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 | Respond with the OpenAPI specification example with a given name. |
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. |
and() |
all | Syntactic sugar to improve readability of respond statements. |
template() |
all | Treat the response file or data as a template with placeholders. |
You structure your response behaviours like so:
respond() // ... behaviours go here
For example:
respond()
.withStatusCode(201)
.skipDefaultBehaviour()
Or:
respond()
.withFile('static-data.json')
.usingDefaultBehaviour()
As we have seen above, to return data when using a script, you specify a response file.
More specifically, to specify which response file to use, you can either:
- set the
file
property within theresponse
object in your configuration, which will be treated as the default, or - explicitly call the
withFile(String)
method in your script.
Here's an example of the static file approach:
# file-example-config.yaml
---
plugin: rest
path: "/scripted"
contentType: application/json
response:
scriptFile: example.groovy
file: example-data.json
Here, the response file example-data.json
will be used, unless the script invokes the
withFile(String)
method with a different filename.
In order for the mock server to return the response file in an appropriate format, the plugin must be allowed to process it. That means you should not call skipDefaultBehaviour()
unless you want to skip using a response file (e.g. if you want to send an error code back or a response without a body).
Whilst not required, your script could invoke usingDefaultBehaviour()
for readability to indicate that you want the plugin to handle the response file for you. See the rest plugin tests for a working example. To this end, the following blocks are semantically identical:
respond()
.withFile('static-data.json')
.usingDefaultBehaviour()
and:
respond().withFile('static-data.json')
You can set response headers using the withHeader(String, String)
method.
respond().withHeader('X-Custom-Header', 'example value')
You can return raw data using the withContent(String)
method.
respond().withContent('{ "someKey": "someValue" }')
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.