Simple, Fast and Powerful file-based Node.js mock server
Mockiji is a generic Node.js REST API server.
Provided a JSON/HTML file, named along rules, it will create a REST route which will serve the file as the response.
Plus, you can also provide a JavaScript file to generate a response according to the request context.
Request: GET /api/of/mine
Response: HTTP 200 OK
{
"title": "The response to GET /api/of/mine (HTTP 200 OK)",
"description": "This filepath is /api/of/mine/get.json"
}
Request: POST /api/books/
Response: HTTP 503 Service Unavailable
{
"title": "This is a 503 HTTP Error to the request POST /api/books/",
"description": "This filepath is /api/books/post.503.json"
}
When Mockiji receives a request, it looks at the HTTP verb (GET
, POST
, etc.) and its path (/api/elem1/elem2
) before looking for a mock file matching it.
As an example:
The first file matching one of these patterns is served.
As you can see, Mockiji will try to match specific requests first,
then it will try to get more generic thanks to the @default
token
which may fit a folder name in the mocks folder hierarchy.
Mockiji contains some mocks to start playing with and help you understand how it works. This first API is a library (the ones with books) where users kate and tom has borrowed some books. Please install and launch Mockiji without editing the default configuration and let's get started.
Start by loading http://localhost:8080/api-simple-library/users/tom/books
in your browser or REST Client (GET
verb).
These are the books borrowed by tom.
If you look at the Response Headers you will see a X-Mockiji-File
like this:
X-Mockiji-File: /srv/www/mockiji/mocks/api-simple-library/users/tom/books/get.json
It means the response content has been served from this file.
You can verify this by yourself by checking the content of this local file defined by X-Mockiji-File
.
If you replace "tom" by "alex" in the URL, you will receive another response.
X-Mockiji-File: /srv/www/mockiji/mocks/api-simple-library/users/@default/get_books.json
What is this @default
part in the path? It is a special token used by Mockiji.
Mockiji has tried to load a file with an "alex" in the path but he has not found any.
Then it tried to replace some parts from the URL with this special token @default
.
That's why this file has been served. Look at the file hierarchy in the api-simple-library
to understand.
Now we will request a non-existing request for this api.
Try this one: http://localhost:8080/api-simple-library/users/kate/comics
You should get a page looking like this one:
{
"errorCode": 404,
"errorDescription": "No mock file was found",
"evaluatedMockFilePaths": [
"/srv/www/mockiji/mocks/api-simple-library/users/kate/comics/get.*",
"/srv/www/mockiji/mocks/api-simple-library/users/kate/get_comics.*",
"/srv/www/mockiji/mocks/api-simple-library/users/get_kate_comics.*",
"/srv/www/mockiji/mocks/api-simple-library/get_users_kate_comics.*",
"/srv/www/mockiji/mocks/api-simple-library/users/kate/@default/get.*",
"/srv/www/mockiji/mocks/api-simple-library/users/@default/comics/get.*",
"/srv/www/mockiji/mocks/api-simple-library/@default/kate/comics/get.*",
"/srv/www/mockiji/mocks/@default/users/kate/comics/get.*",
"/srv/www/mockiji/mocks/api-simple-library/users/@default/get_comics.*",
"/srv/www/mockiji/mocks/api-simple-library/@default/kate/get_comics.*",
"/srv/www/mockiji/mocks/@default/users/kate/get_comics.*",
"/srv/www/mockiji/mocks/api-simple-library/@default/get_kate_comics.*",
"/srv/www/mockiji/mocks/@default/users/get_kate_comics.*",
"/srv/www/mockiji/mocks/@default/get_users_kate_comics.*"
]
}
No mock file was found and Mockiji tells you where it searched for mock files. This page is useful to understand why your mock file has not been found. You can also use theses paths to choose where to create your files for improving the API.
If you create one file and put it on one of these paths, you will be able to refresh your URL and see it served.
What happens if you create one JSON mock file but screwed up and put XML in it?
Try it by yourself you will get:
{
"errorCode": 500,
"errorDescription": "The mock file contains invalid JSON"
}
As usual, you can locate the served file with the X-Mockiji-File
response header and fix it with nice and valid JSON.
You can install Mockiji using npm, either globally or as a dev dependency of your project:
# Globally
npm install -g mockiji
# As a dev dependency
npm install --save-dev mockiji
Then to run it, just execute the mockiji
binary:
mockiji
Note: By default Mockiji will expect a mocks/
directory where the command is executed. You can use the one at the root of this repository as an example.
With Docker
Mockiji is not yet available on Docker hub, however you can build an image easily.
You must have docker installed along with the docker
command.
From the app root folder:
docker build -t mockiji .
From the app root folder:
docker run -d -p 8080:8080 mockiji ./bin/mockiji
Without Docker
You can use your favorite package manager and node process manager.
You MUST have Node >= 6
and NPM >= 3
.
You MAY have yarn
and pm2
.
Please choose one of the following install option:
Install with yarn
From the root folder:yarn
Install with npm
From the root folder:npm install
Launch with pm2
From the root folder:pm2 start src/index.js --name="mockiji-api"
Launch with Node
From the root folder:./bin/mockiji
You should now be able to load http://localhost:8080
in your browser or REST client now.
Mockiji embeds a default configuration that works out of the box and loads mocks from the mocks/
folder.
You can override it using the following methods.
Note: All path are relative to the directory Mockiji is started from.
Usage: PORT=8001 API_BASE_PATH=./my-mocks/ mockiji
Name | Type | Default | Description |
---|---|---|---|
PORT | port | 8080 | Listening port |
NODE_ENV | string | dev | Environment name |
API_BASE_PATH | path | ./mocks | Path to the folder containg mock files |
Usage: mockiji --port 8001 --api-base-path ./my-mocks/
Name | Type | Default | Description |
---|---|---|---|
config-file | string | Path to a configuration file | |
port | port | 8080 | Listening port |
env | string | dev | Environment name |
api-base-path | path | ./mocks | Path to the folder containg mock files |
silent | If specified, disable the default stdout log stream |
The whole node-convict configuration schema can be found in the src/utils/configuration.js
file.
You can override the default values by specifying a JSON configuration file when running Mockiji, e.g. mockiji --config-file mockiji.json
.
You will have to restart Mockiji if you want the configuration to change.
If you use pm2, you can do it with pm2 restart 0
(provided 0 is your mockiji pm2-process id)
You can also start a mockiji server directly from your code by using its API:
const Mockiji = require('mockiji');
const server = new Mockiji({
configuration: {
port: 8001,
api_base_path: './my-mocks',
}
});
server.start().then(
() => { console.log('Mockiji started'); },
(error) => { console.error('Could not start Mockiji: ', error); }
);
The Mockiji
constructor takes an option object as a parameter that can have the following attributes:
configuration
: a configuration object as described by the node-convict configuration schema that can be found in thesrc/utils/configuration.js
file;configFile
: a path to a JSON configuration file.
An instance of Mockiji
provides two methods start
and stop
both returning a Promise
object.
Log files are generated by Bunyan and are saved by default in the logs/
folder.
This behavior can by adding Bunyan streams to the logs
attribute of the configuration file described previously.
A default stdout
stream with the debug
or info
level (based on whether or not your are using the dev
environment) is also automatically added and can be disabled using the --silent
argument.
As an example, using the configuration file:
{
"logs": [{
"filepath": "./logs/api-mockiji.log",
"level": "warn",
"type": "rotating-file",
"period": "1d",
"count": 3
}]
}
Available parameters for each stream can be found in the Bunyan documentation.
A Mockiji middleware is a JavaScript function that is called by Mockiji (with the logger
and the configuration
as a parameter) and returns an Express middleware.
This Express middleware is then added before to the ones used by Mockiji.
Here is a simple example that retrieves the response time for every request and logs it using Mockiji's logger:
const Mockiji = require('mockiji');
const server = new Mockiji({
configuration: {
middlewares: [
({logger, configuration}) => {
logger.info('Response time middleware loaded');
return (req, res, next) => {
// On request received
const requestTime = Date.now();
// On request end
req.on('end', _ => {
const deltaTime = Date.now() - requestTime;
logger.debug(`Request ${req.method} ${req.originalUrl} took ${deltaTime}ms`);
});
// Call next middleware
next();
}
}
]
}
});
server.start();
It is also possible to create a standalone middleware and then reuse it between projects:
const express = require('express');
module.exports = function({basePath} = {}) {
return ({logger, configuration}) => {
logger.info('Mockiji custom middleware loaded');
const app = express();
app.use(basePath, require('./routes'));
return app;
};
}
const Mockiji = require('mockiji');
const server = new Mockiji({
configuration: {
middlewares: [
require('my-custom-middleware')({basePath: '/dashboard'})
]
}
});
server.start();