Parameter | Type | Description |
---|---|---|
shellTransform |
A string | Represents the path to a command line application. The application should
retrieve the JSON-encoded request and response from the environment
and print out the transformed response to stdout .
|
The shellTransform
behavior plays a similar role as the decorate
behavior,
enabling a programmatic transformation of the response. However, you don't have to write the transformation
logic in JavaScript -- it can be in the language of your choice.
mountebank will expose the following environment variables to your shell application:
MB_REQUEST
which contains the JSON request as a string, andMB_RESPONSE
which contains the current JSON response as a stringThe application should write to stdout a JSON representation of the transformed response.
We'll show a simple example of shelling out to plug in response values based on an external data source.
At times you may find it convenient to use an external data store to fill in dynamic values based on
data coming in from the request. You can combine an is
canned response with a
shellTransform
behavior to achieve this, regardless of what the external data source is.
For this example, we'll assume it's a simple pipe-delimited file mapping customer ids to names. We'll
save it as names.csv
in the directory we run mb
from.
123|Frodo Baggins
234|Samwise Gamgee
345|Gandalf the White
456|Smeagol
We expect the incoming http request to specify the id in the URL, and we want to represent the name in the response body. We'll set up our imposter like this:
POST /imposters HTTP/1.1
Host: localhost:<%= port %>
Accept: application/json
Content-Type: application/json
{
"port": 5555,
"protocol": "http",
"stubs": [
{
"predicates": [{ "matches": { "path": "/accounts/\\d+" } }],
"responses": [
{
"is": { "body": "Hello, ${YOU}!" },
"behaviors": [
{ "shellTransform": "node <%= process.cwd() %>/addName.js" }
]
}
]
}
]
}
In this example, we're shelling out to a node.js application, which isn't much different than
using a decorate
function. However, that's just to keep it simple; the application
could be written in any language.
Let's create the addName.js
file..
var request = JSON.parse(process.env.MB_REQUEST),
response = JSON.parse(process.env.MB_RESPONSE),
requestId = request.path.replace('/accounts/', ''),
fs = require('fs'),
mappings = fs.readFileSync('<%= process.cwd() %>/names.txt', { encoding: 'utf8' }),
lines = mappings.split(/\r?\n/);
for (let i = 0; i < lines.length; i += 1) {
var fields = lines[i].split('|'),
id = fields[0],
name = fields[1];
if (requestId === id) {
response.body = response.body.replace('${YOU}', name);
}
}
console.log(JSON.stringify(response));
Now we can test it out:
GET /accounts/234 HTTP/1.1
Host: localhost:5555
HTTP/1.1 200 OK
Connection: close
Date: Wed, 07 Jan 2016 21:27:14 GMT
Transfer-Encoding: chunked
Hello, Samwise Gamgee!
And again...
GET /accounts/456 HTTP/1.1
Host: localhost:5555
HTTP/1.1 200 OK
Connection: close
Date: Wed, 07 Jan 2016 21:27:14 GMT
Transfer-Encoding: chunked
Hello, Smeagol!
DELETE /imposters/5555 HTTP/1.1
Host: localhost:<%= port %>