Apimocker
node.js module to run a simple http server for mock service responses.
Install / Use
/learn @gstroup/ApimockerREADME
apimocker 
This is a node.js module to run a simple http server, which can serve up mock service responses. Responses can be JSON or XML to simulate REST or SOAP services. Access-Control HTTP Headers are set by default to allow CORS requests. Mock services are configured in the config.json file, or on the fly, to allow for easy functional testing. Apimocker can return different responses or HTTP status codes, based on request parameters - even complex JSON requests. Using apimocker, you can develop your web or mobile app with no dependency on back end services. (There are lots of these projects out there, but I wrote this one to support all kinds of responses, to allow on-the-fly configuration, and to run in node.)
Installation
sudo npm install -g apimocker
That will install globally, and allow for easier usage. (On Windows, you don't need "sudo".)
Usage
apimocker \[-c, --config <path>\] \[-q, --quiet\] \[-p <port>\] \[-f, --proxy <proxyURL>\] \[-i, --intercept <proxyIntercept>\]
Out of the box, you can just run "apimocker" with no arguments. (Except on windows, you'll need to edit config.json first. See below.)
Then you can visit "http://localhost:7878/first" in your browser to see it work. The quiet and port options can also be set in the config.json file, and values from config.json will override values from the command line. After you get up and running, you should put your config.json and mock responses in a better location. It's not a good idea to keep them under the "node_modules" directory. Make sure another process is not already using the port you want. If you want port 80, you may need to use "sudo" on Mac OSX.
Windows note
After installing from npm, you may need to edit this file: /Users/xxxxx/AppData/Roaming/npm/node_modules/apimocker/config.json Change the "mockDirectory" to point to this location. (Or another location where you put the mock responses.) mockDirectory: /Users/xxxxx/AppData/Roaming/npm/node_modules/apimocker/samplemocks
Proxy
Sometimes you only want some service endpoints to be mocked, but have other requests forwarded to real service endpoints.
In this case, provide the proxy URL option on startup e.g.
apimocker --proxy http://myrealservice.io
When the proxy option is set, any requests to apimocker with URLs that are not configured with mock files, will be forwarded to the specified URL.
A proxy intercept function can be specified to modify responses, using the proxy intercept option (apimocker --proxy http://myrealservice.io --intercept config/proxyResponseCustomizer`). The value of the option should be the path, relative to the current working directory, to a module that exports an intercept function as documented in the express-http-proxy docs.
Uploads
There is a simple support of multipart form data upload process of a single or multiple files. A global option uploadRoot determines where the files will be saved after successful upload, and another option - useUploadFieldname tells apimocker (actually - multer) whether to save the uploaded file with the original filename found in the request (default), or the name of the field. Although the latter may sound strange, it can make certain testing procedure simpler.
With Grunt or Gulp
If you're using Grunt for your project, there's a grunt plugin you can use to start up apimocker: https://github.com/gstroup/grunt-apimocker
For Gulp, there's also a plugin contributed by kent-wu: https://github.com/kent-wu/gulp-apimocker
Running in Cloud Foundry
You can deploy apimocker into a cloud foundry instance by running cf push. The port you specify will be ignored, and you'll use the standard port 80 to access apimocker. When specifying your mockDirectory, you will need to use a relative path, like "samplemocks/". At this time, you'll need to do another build and push whenever you change a mock file.
Help
apimocker -h
Configuration
On startup, config values are loaded from the config.json file. During runtime, mock services can be configured on the fly. See the sample config.json file in this package.
- Config files can be either
.jsonformat, or in.js. When using.js, the module should export a config object, or a function that returns a config object. - Services can be configured to return different responses, depending on a request parameter or request header.
- Content-type for a service response can be set for each service. If not set, content-type defaults to application/xml for .xml files, and application/json for .json files.
- HTTP Status code can be set for each service.
- Latency (ms) can be set to simulate slow service responses. Latency can be set for a single service, or globally for all services.
- Allowed domains can be set to restrict CORS requests to certain domains.
- Allowed headers can be set. (Default is to set "access-control-allow-headers: Content-Type" if not specified in config file.)
- config.json file format has changed with the 0.1.6 release. See below for the new format. (Old config.json file format is deprecated and doesn't support new features, but still functioning.)
- mockDirectory value can include tilde (~) for user's home directory.
- A basepath can be specified to set a prefix on all web services. Preceding slash is required. For instance if basepath is set to "/apimocker", then all requests must go to "http://localhost:7878/apimocker/..."
- A static route can be opened up to serve up static assets like images. Both staticDirectory and staticPath must be set. If either is not set, then nothing happens.
- Additional headers can be defined for responses, in the
headersobject. Different headers could be returned for different requests, by enabling a switch. - Request headers can be logged, with the
logRequestHeaderssetting. - Alternate URL paths can be specified with the
alternatePathssetting. - With the
enableTemplatesetting, values from the request can be inserted into the mock response. - With the
templateSwitchsetting, parameter names and values from the request can be mapped and inserted into the mock response, including POST requests and powerful JSONPath parameter substitution into a JSON POST body. - Set the
allowAvoidPreFlightconfig option to true to allow requests sent withContent-Type: text/plainto be processed as json if possible. (default is false). This allows apimocker to work with servers such as Parse Server.
{
"note": "This is a sample config file. You should change the mockDirectory to a more reasonable path.",
"mockDirectory": "/usr/local/lib/node_modules/apimocker/samplemocks/",
"staticDirectory": "/optional/file/system/path/to/static/directory",
"staticPath": "/optional/web/path/to/static/directory",
"quiet": false,
"port": "7878",
"latency": 50,
"logRequestHeaders": false,
"allowedDomains": ["abc.com"],
"allowedHeaders": ["Content-Type", "my-custom-header"],
"corsCredentials": "true",
"webServices": {
"first": {
"mockFile": "king.json",
"latency": 20,
"verbs": ["get"],
"alternatePaths": ["1st"]
},
"second": {
"verbs": ["delete", "post"],
"responses": {
"delete": {"httpStatus": 204},
"post": {
"contentType": "foobar",
"mockFile": "king.json"
}
}
},
"nested/ace": {
"mockFile": "ace.json",
"verbs": ["post", "get"],
"switch": "customerId"
},
"nested/ace2": {
"mockFile": "ace.json",
"verbs": ["post", "get"],
"switch": ["customerId","multitest"]
},
"var/:id": {
"mockFile": "xml/queen.xml",
"verbs": ["all"],
"switch": "id"
},
"login": {
"verbs": ["post"],
"switch": ["userId", "password"],
"responses": {
"post": {"httpStatus": 401, "mockFile": "sorry.json"}
},
"switchResponses": {
"userIduser1passwordgood": {"httpStatus": 200, "mockFile": "king.json"},
"userIdadminpasswordgood": {"httpStatus": 200}
}
},
"nested/aceinsleeve": {
"verbs": [
"post"
],
"switch": "$..ItemId[(@.length-1)]",
"responses": {
"post": {"httpStatus": 200, "mockFile": "aceinsleeve.json"}
},
"switchResponses": {
"$..ItemId[(@.length-1)]4": {"httpStatus": 500, "mockFile": "ItemId4.aceinsleeve.json"}
}
},
"firstheaders": {
"mockFile": "king.json",
"contentType": "foobar",
"headers": {
"x-requested-by": "4c2df03a17a803c063f21aa86a36f6f55bdde1f85b89e49ee1b383f281d18c09c2ba30654090df3531cd2318e3c",
"dummyheader": "dummyvalue"
},
"verbs": ["get"]
},
"template/:Name/:Number" :{
"mockFile": "templateSample.json",
"verbs":["get"],
"enableTemplate": true,
"contentType":"application/json"
},
"raw": {
"mockBody": "{ \"text\" : \"Good Job!\" }",
"verbs": ["all"]
}
}
}
The most interesting part of the configuration file is the webServices section.
This section contains a JSON object describing each service. The key for each service object is the service URL (endpoint.) Inside each service object, the mockFile (or mockBody) and verbs are required. All other attributes of the service objects are optional.
For instance, a GET request sent to "http://server:port/first" will return the king.json file from the samplemocks directory, with a 20 ms delay. Alternatively one can specify the mockBody directly, bypassing the need for a specific mock file.
If you'd like to return different responses for a sin
