Contracts
To get more details on any field, simply hover your mouse over that field. Purple fields are only meaningful in the response; they will be ignored in any requests.
Showing contract for the resource.
{
"_links": {
"imposters": {
"href": "http://localhost:2525/imposters"
},
"config": {
"href": "http://localhost:2525/config"
},
"logs": {
"href": "http://localhost:2525/logs"
}
}
}
{
"imposters": [
{
"protocol": "http",
"port": 4546,
"_links": {
"self": {
"href": "http://localhost:2525/imposters/4546"
}
}
}
]
}
{
"port": 4545,
"protocol": "https",
"name": "imposter contract service",
"recordRequests": "true",
"numberOfRequests": "1",
"key": "-----BEGIN RSA PRIVATE KEY-----\nMIICXAIBAAKBgQCrvse04YkxtVGagyvGJCsvv7LTfLK5uR/ZIJKDYCnuF+BqBzM4\nlko8O39vx+Lz9FfF11Xl+CN1aY37YurLYOle3dC/qslSbQDe2TJN7lcVHVssePvc\nO5IExpvNFV5LYtmyCMKJHxpnIprv/trUso5obqzzXhFVPV9SQbFH/snInwIDAQAB\nAoGARywlqLD6YO4qJiULw+4DM6N2oSwBCPRN3XYhIW59kdy1NFtNf7rQgsuJUTJ9\nu+lbYnKNd2LwltyqaS4h7Sx5KRhpFNmMpyVsBf5J2q3fbfmrsXt+emY7XhVTc1NV\nizUWYyxCoTTeMWvN/6NYpPV0lSxq7jMTFVZrWQUMqJclxpECQQDTlGwALtAX1Y8u\nGKsEHPkoq9bhHA5N9WAboQ4LQCZVC8eBf/XH//2iosYTXRNgII2JLmHmmxJHo5iN\nJPFMbnoHAkEAz81osJf+yHm7PBBJP4zEWZCV25c+iJiPDpj5UoUXEbq47qVfy1mV\nDqy2zoDynAWitU7PeHyZ8ozfyribPoR2qQJAVmvMhXKZmvKnLivzRpXTC9LMzVwZ\nV6x/Wim5w8yrG5fZIMM0kEG2xwR3pZch/+SsCzl/0aLLn6lp+VT6nr6NZwJBAMxs\nHrvymoLvNeDtiJFK0nHliXafP7YyljDfDg4+vSYE0R57c1RhSQBJqgBV29TeumSw\nJes6cFuqeBE+MAJ9XxkCQDdUdhnA8HHQRNetqK7lygUep7EcHHCB6u/0FypoLw7o\nEUVo5KSEFq93UeMr3B7DDPIz3LOrFXlm7clCh1HFZhQ=\n-----END RSA PRIVATE KEY-----",
"cert": "-----BEGIN CERTIFICATE-----\nMIIB6TCCAVICCQCZgxbBD0CG4zANBgkqhkiG9w0BAQUFADA5MQswCQYDVQQGEwJV\nUzETMBEGA1UECBMKU29tZS1TdGF0ZTEVMBMGA1UEChMMVGhvdWdodFdvcmtzMB4X\nDTEzMTIyOTE2NDAzN1oXDTE0MDEyODE2NDAzN1owOTELMAkGA1UEBhMCVVMxEzAR\nBgNVBAgTClNvbWUtU3RhdGUxFTATBgNVBAoTDFRob3VnaHRXb3JrczCBnzANBgkq\nhkiG9w0BAQEFAAOBjQAwgYkCgYEAq77HtOGJMbVRmoMrxiQrL7+y03yyubkf2SCS\ng2Ap7hfgagczOJZKPDt/b8fi8/RXxddV5fgjdWmN+2Lqy2DpXt3Qv6rJUm0A3tky\nTe5XFR1bLHj73DuSBMabzRVeS2LZsgjCiR8aZyKa7/7a1LKOaG6s814RVT1fUkGx\nR/7JyJ8CAwEAATANBgkqhkiG9w0BAQUFAAOBgQCPhixeKxIy+ftrfPikwjYo1uxp\ngQ18FdVN1pbI//IIx1o8kJuX8yZzO95PsCOU0GbIRCkFMhBlqHiD9H0/W/GvWzjf\n7WFW15lL61y/kH1J0wqEgoaMrUDjHZvKVr0HrN+vSxHlNQcSNFJ2KdvZ5a9dhpGf\nXOdprCdUUXzSoJWCCg==\n-----END CERTIFICATE-----",
"mutualAuth": false,
"defaultResponse": {
"statusCode": 400,
"body": "Bad Request",
"headers": {}
},
"stubs": [
{
"responses": [
{
"is": {
"statusCode": 201,
"headers": {
"Location": "http://example.com/resource"
},
"body": "The time is ${TIME}",
"_mode": "text"
},
"repeat": 3,
"behaviors": [
{ "wait": 500 },
{ "decorate": "config => { config.response.body = config.response.body.replace('${TIME}', 'now'); }" },
{ "shellTransform": "transformResponse" },
{
"copy": {
"from": "body",
"into": "${NAME}",
"using": {
"method": "xpath",
"selector": "//test:name",
"ns": { "test": "http://example.com/test" }
}
}
},
{
"lookup": {
"key": {
"from": { "headers": "If-Modified-Since" },
"using": {
"method": "regex",
"selector": "(\\w+), (\\d+) (\\w+) (\\d+)",
"options": { "ignoreCase": true, "multiline": true }
},
"index": 2
},
"fromDataSource": {
"csv": {
"path": "values.csv",
"keyColumn": "month",
"delimiter": ","
}
},
"into": "${row}"
}
}
]
},
{
"proxy": {
"to": "https://www.somesite.com:3000",
"mode": "proxyAlways",
"key": "-----BEGIN RSA PRIVATE KEY-----\nMIICXAIBAAKBgQCrvse04YkxtVGagyvGJCsvv7LTfLK5uR/ZIJKDYCnuF+BqBzM4\nlko8O39vx+Lz9FfF11Xl+CN1aY37YurLYOle3dC/qslSbQDe2TJN7lcVHVssePvc\nO5IExpvNFV5LYtmyCMKJHxpnIprv/trUso5obqzzXhFVPV9SQbFH/snInwIDAQAB\nAoGARywlqLD6YO4qJiULw+4DM6N2oSwBCPRN3XYhIW59kdy1NFtNf7rQgsuJUTJ9\nu+lbYnKNd2LwltyqaS4h7Sx5KRhpFNmMpyVsBf5J2q3fbfmrsXt+emY7XhVTc1NV\nizUWYyxCoTTeMWvN/6NYpPV0lSxq7jMTFVZrWQUMqJclxpECQQDTlGwALtAX1Y8u\nGKsEHPkoq9bhHA5N9WAboQ4LQCZVC8eBf/XH//2iosYTXRNgII2JLmHmmxJHo5iN\nJPFMbnoHAkEAz81osJf+yHm7PBBJP4zEWZCV25c+iJiPDpj5UoUXEbq47qVfy1mV\nDqy2zoDynAWitU7PeHyZ8ozfyribPoR2qQJAVmvMhXKZmvKnLivzRpXTC9LMzVwZ\nV6x/Wim5w8yrG5fZIMM0kEG2xwR3pZch/+SsCzl/0aLLn6lp+VT6nr6NZwJBAMxs\nHrvymoLvNeDtiJFK0nHliXafP7YyljDfDg4+vSYE0R57c1RhSQBJqgBV29TeumSw\nJes6cFuqeBE+MAJ9XxkCQDdUdhnA8HHQRNetqK7lygUep7EcHHCB6u/0FypoLw7o\nEUVo5KSEFq93UeMr3B7DDPIz3LOrFXlm7clCh1HFZhQ=\n-----END RSA PRIVATE KEY-----",
"cert": "-----BEGIN CERTIFICATE-----\nMIIB6TCCAVICCQCZgxbBD0CG4zANBgkqhkiG9w0BAQUFADA5MQswCQYDVQQGEwJV\nUzETMBEGA1UECBMKU29tZS1TdGF0ZTEVMBMGA1UEChMMVGhvdWdodFdvcmtzMB4X\nDTEzMTIyOTE2NDAzN1oXDTE0MDEyODE2NDAzN1owOTELMAkGA1UEBhMCVVMxEzAR\nBgNVBAgTClNvbWUtU3RhdGUxFTATBgNVBAoTDFRob3VnaHRXb3JrczCBnzANBgkq\nhkiG9w0BAQEFAAOBjQAwgYkCgYEAq77HtOGJMbVRmoMrxiQrL7+y03yyubkf2SCS\ng2Ap7hfgagczOJZKPDt/b8fi8/RXxddV5fgjdWmN+2Lqy2DpXt3Qv6rJUm0A3tky\nTe5XFR1bLHj73DuSBMabzRVeS2LZsgjCiR8aZyKa7/7a1LKOaG6s814RVT1fUkGx\nR/7JyJ8CAwEAATANBgkqhkiG9w0BAQUFAAOBgQCPhixeKxIy+ftrfPikwjYo1uxp\ngQ18FdVN1pbI//IIx1o8kJuX8yZzO95PsCOU0GbIRCkFMhBlqHiD9H0/W/GvWzjf\n7WFW15lL61y/kH1J0wqEgoaMrUDjHZvKVr0HrN+vSxHlNQcSNFJ2KdvZ5a9dhpGf\nXOdprCdUUXzSoJWCCg==\n-----END CERTIFICATE-----",
"ciphers": "RC4-MD5",
"secureProtocol": "TLSv1_1_method",
"passphrase": "LetMeIn!",
"addWaitBehavior": "true",
"addDecorateBehavior": "(request, response) => { response.body = response.body.replace('${TIME}', 'now'); }",
"predicateGenerators": [
{
"matches": {
"path": true
},
"caseSensitive": true,
"except": "^The^",
"jsonpath": {
"selector": "$..book"
},
"xpath": {
"selector": "//book/@title",
"ns": {
"isbn": "http://schemas.isbn.org/ns/1999/basic.dtd"
}
},
"inject": "function (config) { return []; }",
"ignore": { "query": "startDate" }
}
],
"injectHeaders": {
"X-Custom-Header": "Served by mountebank"
}
}
},
{
"inject": "function (config) { config.callback({ body: 'It worked!' }); }"
}
],
"predicates": [
{
"equals": {
"body": "value"
},
"caseSensitive": true,
"except": "^The ",
"jsonpath": {
"selector": "$..book"
},
"xpath": {
"selector": "//book/@title",
"ns": {
"isbn": "http://schemas.isbn.org/ns/1999/basic.dtd"
}
}
},
{
"inject": "function (config) { return config.request.body.length < 100; }"
}
],
"matches": [
{
"timestamp": "2014-01-09T02:30:31.043Z",
"request": {
"requestFrom": "::ffff:127.0.0.1:60523",
"method": "POST",
"path": "/imposters",
"query": {},
"headers": {
"accept": "text/plain",
"host": "localhost:4545",
"content-type": "application/xml",
"connection": "keep-alive",
"transfer-encoding": "chunked"
},
"body": "<books><book title='The value' /></books>"
},
"response": {
"statusCode": 201,
"headers": {
"Location": "http://example.com/resource"
},
"body": "The time is now",
"_mode": "text"
}
}
]
}
],
"endOfRequestResolver": {
"inject": "function (config) { return config.request.length >= 100; }"
},
"requests": [
{
"timestamp": "2014-01-09T02:30:31.043Z",
"requestFrom": "::ffff:127.0.0.1:60523",
"method": "POST",
"path": "/imposters",
"query": {},
"headers": {
"accept": "text/plain",
"host": "localhost:4545",
"content-type": "text/plain",
"connection": "keep-alive",
"transfer-encoding": "chunked"
},
"body": "Just checking"
}
],
"_links": {
"self": {
"href": "http://localhost:2525/imposters/4545"
}
}
}
{
"index": 1,
"stub": {
"responses": [{
"is": {
"body": "Hello, world!"
}
}]
}
}
{
"responses": [{
"is": {
"body": "Hello, world!"
}
}]
}
{
"stubs": [
{
"responses": [{
"is": {
"body": "Hello, world!"
}
}]
}
]
}
{
"version": "1.4.1",
"options": {
"port": 2525,
"pidfile": "mb.pid",
"logfile": "mb.log",
"loglevel": "info",
"configfile": "",
"allowInjection": false,
"mock": true,
"debug": true
},
"process": {
"nodeVersion": "v6.9.1",
"architecture": "x64",
"platform": "darwin",
"rss": 29822976,
"heapTotal": 18635008,
"heapUsed": 9294352,
"uptime": 16,
"cwd": "/Users/bbyars/src/mountebank"
}
}
{
"logs": [
{
"level": "info",
"message": "[mb:2525] mountebank v1.4.1 (node v4.2.0) now taking orders - point your browser to http://localhost:2525 for help",
"timestamp": "2015-10-20T02:24:41.818Z"
},
{
"level": "info",
"message": "[mb:2525] Adios - see you soon?",
"timestamp": "2015-10-20T02:31:38.109Z"
}
]
}
Defines the hypermedia relationships for mountebank.
Defines the URL for the imposters resource.
Defines the URL for the config resource.
Defines the URL for the log resource.
An array of imposter objects.
A single imposter object.
The port to run the imposter on.
Optional. Defaults to a randomly assigned port that will be returned in the response
Optional. Allows you to provide a descriptive name that will show up in the logs and the imposters UI.
Optional. If set to true
, the server will record requests received, for mock verification purposes.
The number of requests to this imposter
Optional. Allows you to pass in an SSL private key for creating an https server (this field only applies to https). Must be a PEM-formatted string. Defaults to a built-in private key.
Optional. Allows you to pass in an SSL certificate for creating an https server (this field only applies to https). Must be a PEM-formatted string. Defaults to a built-in self-signed certificate.
Optional. If set to true
, the server will request a client certificate. Since the goal
is simply to virtualize a server requiring mutual auth, invalid certificates will not be rejected.
Optional. Allows you to override the default response that mountebank sends back if no predicate matches a request. Even if a predicate does match but the response isn't fully specified, these values get merged in to complete the response.
A set of behaviors used to generate a response for an imposter. An imposter can have 0 or more stubs, each of which are associated with different predicates and support different responses.
You would use multiple stubs for an imposter if the types of response you return depends on something in the request, matched with a predicate.
An array of responses to return for this stub. The responses array defines a circular buffer - every
time the stub is used for the request, the first response is pulled from the front of the
responses
array, evaluated, and pushed to the back of the array. This elegantly does what
you want. In the common case, when you always want to return the same response, you just add one response
to the array. More complex scenarios will require that the same endpoint returns a sequence of
different responses for the same predicates. Simply add them all to the array in order.
When the sequence finishes, it will start over. More complexity can be added by simply
adding more responses to the array without complicating the contract.
Each response is defined by one and only one response type. This defines the type of response generated. The following response types are supported, and described in more detail in the contract example to the left as well as the links provided below.
The is
response type represents a canned response that you define. The response fields will
be those defined with each protocol according to the links below (the http response fields
are shown in this example). smtp stubbing is not supported.
You do not need to fill in every response field; mountebank will merge the specified response fields with the response defaults (see the protocol pages below for the defaults).
Causes the response to repeat a given number of times before returning the next response
in the responses
array.
Behaviors alter the generated response in some way. The following behaviors are supported:
wait
- adds latency to the responsedecorate
- post-processes the response using a JavaScript functionshellTransform
- post-processes the response using a command line applicationcopy
- copies a value from the request into the responselookup
- lookups values from an external data source
More information: behaviors
Adds latency to a response by waiting a specified number of milliseconds before sending the response.
Post-processes the response before sending it. Since post-processing requires JavaScript
injection, the --allowInjection
flag must be passed.
Post-processing opens up a world of opportunities - you can use a decorate
behavior
to add data to a proxied response or substitute dynamic data into the response, for
example. The value passed into the decorate
behavior is a JavaScript function that
can take up to an object containing the request, the response, and a logger. You can either mutate the
response passed in (and return nothing), or return an altogether new response.
Post-processes the response before sending it. Unlike a decorate
, the post-processing
occurs through a command line application, which still requires the
--allowInjection
flag to be set. The command line application will be passed the request JSON
and the response JSON through environment variables, and should write the transformed response
JSON to stdout
.
Post-processes the response by replacing the given tokens with values from the specified request fields. You can select the appropriate values from the request using regular expressions, xpath, or jsonpath.
Post-processes the response by looking up data from an external data source using a key selected from the request. The given tokens in the response are replaced with the looked up values. You can select the appropriate keys from the request using regular expressions, xpath, or jsonpath.
The response is generated by proxying the request to a different server. You can configure mountebank to return the saved response on subsequent requests based on certain conditions within the request.
Represents the destination to send the request. This should be a URL with the protocol and host but without a path (as shown to the left). http and https imposters can both proxy to http and https. tcp proxies can only proxy to tcp (e.g. tcp://someserver:3000).
Defines the replay behavior of the proxy. Proxy responses work by creating new elements in the
stubs
array. This field determines whether that newly created stub will be before or
after the current stub in the array. There are two options:
proxyOnce
- always records the proxied call in thestubs
array in front of itself, so the same call is never proxied twice.proxyAlways
- saves the proxied call after itself in thestubs
array. This allows you to capture different responses for the same call. You can later replayproxyAlways
stubs by issuing aGET
orDELETE
to the imposter with theremoveProxies
andreplayable
query params, and re-POST
ing the imposter.
In situations where the destination expects to use SSL mutual authentication, it will request a client certificate. This field can contain the PEM-formatted client private key.
In situations where the destination expects to use SSL mutual authentication, it will request a client certificate. This field can contain the PEM-formatted client certificate.
In nearly all cases, you'll never need to use this field. However if you need to proxy to an older HTTPS server using insecure ciphers that are no longer used, you can override the cipher using one of the standard formats.
A legacy mechanism to select the TLS protocol to use. Learn more at the node documentation.
The shared passphrase for a private key
When this field is true, mountebank will add latency to the saved responses that mirrors the time the actual proxied call took. This is useful in load testing when you want to virtualize downstream services but keep the latency of those services.
When present, adds the given function as a decorate
behavior to each newly created response.
Allows you to add or override headers returned from the proxy.
An array of objects that defines how the predicates for new stubs are created. Proxy responses work
by creating new elements in the stubs
array, either before the current stub (if
mode
is proxyOnce
) or after the current stub (if mode
is
proxyAlways
). Each element in the predicateGenerators
array
will create a single element in the predicates
array for newly created stub.
Each generator should contain a matches
field containing all the request elements you
want to create predicates for. You can configure the newly created predicate with standard predicate
parameters. The created predicates will be generally be deepEquals
predicates.
Alternatively, if you need more fine-grained control, you can use an inject
field
containing a JavaScript function to create the predicates.
mountebank is scriptable, which allows you to use JavaScript to craft the response you want in situations where canned responses and proxy responses are not sufficient. The injected function takes four parameters as shown on the left:
request
- the protocol-specific request objectstate
- initially an empty object, the same instance will be passed into every response injection function within the same imposter. You can use it to add any cross-response state you need to save.logger
- mountebank's logger, with standarddebug
,info
,warn
, anderror
functionscallback
- For asynchronous use only, execute (with the response as a parameter) to return
Injection can by synchronous or asnychronous. Simply return a value representing the response for synchronous
execution. For asynchronous execution, pass the response object into the callback
function.
In the absence of a predicate, a stub always matches, and there's never a reason to add more than one stub to an imposter. Predicates allow imposters to have much richer behavior by defining whether or not a stub matches a request. When multiple stubs are created on an imposter, the first stub that matches is selected.
Each predicate object contains one or more of the request fields as keys. Predicates are added to a stub in an array, and all predicates are AND'd together. The following predicate operators are allowed:
equals
- The request field matches the predicatedeepEquals
- Performs nested set equality on the request field, useful when the request field is an object (e.g. thequery
field in http)contains
- The request field contains the predicatestartsWith
- The request field starts with the predicateendsWith
- The request field ends with the predicatematches
- The request field matches the JavaScript regular expression defined with the predicate.exists
- Iftrue
, the request field must exist. Iffalse
, the request field must not exist.not
- Inverts a predicateor
- Logically or's two predicates togetherand
- Logically and's two predicates togetherinject
- Injects JavaScript to decide whether the request matches or not.
A type of predicate that requires the given request fields to equal the predicate value. By default, mountebank uses a case-insensitive equality.
If true, mountebank will require the request field to satisfy the predicate value in a case sensitive comparison.
Defines a regular expression that is stripped out of the request field before matching.
It is common to want to use predicates on JSON response bodies, but annoying to treat the JSON as
simple text with many of the predicates. mountebank uses the json
predicate parameter
to narrow the scope of the predicate value to a value matched by the json selector.
It is common to want to use predicates on XML response bodies, but annoying to treat the XML as
simple text with many of the predicates. mountebank uses the xpath
predicate parameter
to narrow the scope of the predicate value to a value matched by the xpath selector.
When none of the built-in predicates are sufficient, mountebank allows you to script the predicate. The injected function accepts the following parameters:
request
- the full request objectlogger
- mountebank's logger, with standarddebug
,info
,warn
, anderror
functions
Return true
to pass the predicate.
An array of all activity by this stub, useful in troubleshooting why a stub is or is not
responding (generally for debugging your predicates). Each object will contain the incoming
request>
, the outgoing response
, and a timestamp
.
The tricky bit about using the raw TCP protocol is knowing when a request ends. Application
protocols give some way of determining this, such as the Content-Length
header in
HTTP or by embedding the message length in binary protocols. By default, mountebank assumes
each packet represents a separate request, which typically limits the size of each request
to somewhere between 1500 and 64k bytes (you'll get a larger payload using the loopback interface
on localhost, but lower level protocols like Ethernet will force a smaller payload over the network).
This strategy works for many scenarios as simple serialized requests tend to fall below this size,
but breaks down with large requests.
mountebank allows you the flexibility to determine when a request ends using the
endOfRequestResolver
at the imposter level. The value is a JavaScript function
that takes a parameter that represents all request data captured from all packets so far. If the
imposter is in text
mode, the parameter will be a string; in binary it will be a
node.js Buffer object.
mountebank's logger
object is also passed as an optional second parameter to
assist in troubleshooting.
mountebank will save off all requests to the imposter for mock verification. By retrieving the imposter, your client code can determine if an expected service call was in fact made.
Defines the hypermedia relationships for the imposter.
The array index to add the stub. Stubs are always evaluated in array order, and the first stub whose predicates match the request will be used. If you leave this value off the request, the stub will be added to the end of the array.
The stub to add. See the imposter contract for more information.
The stub to add. See the imposter contract for more information.
The stub to add. See the imposter contract for more information.
The mountebank version
The command line options used to start mb
.
Information about the running mb
process
The version of node.js
The operating system and architecture of the machine running mountebank.
The memory (in bytes) used by mountebank, and heap usage of the V8 JavaScript engine.
The number of seconds this process has been running.
The current directory, used to start mb
An array of all log statements captured in the current log file.