Developing plugins
Preface
In the previous chapters we figured out what Plugins are, and how to install them. Now we are going to see how to create them, so you can extend Mocks Server with your own features easily 🙂.
As mentioned in the plugins intro:
A plugin basically consist on a JavaScript
Class
containing some standardized methods. The Mocks Server core is at charge of creating the plugin instance using the providedClass
and calling to each method on each specific time of the Mocks Server lifecycle. Theconstructor
and theClass
methods will always receive an instance of the Mocks Server core API, so it can be used to tap into, modify, or extend its internal behavior.
Lifecycle
Plugins should contain four main methods, which will receive an argument containing the instance of Mocks Server core API. Please read the API chapter to know how to use the core API
.
constructor(core)
This method is executed for registering the plugin during the Mocks Server initialization, before the configuration
has been initialized.
Here you should register your own custom options
using the core.config
object, register your own custom Express routers using the core.server.addRouter
method, add custom Variant Handlers using core.variantHandlers.register
, etc.
You should never read the configuration values in the constructor
, because the configuration object is not still ready in this phase. Here you should only define your own options.
init(core)
This method is called when Mocks Server configuration is loaded and ready. Here you can already use the core.config
object to read the user options, and act in consequence, and you can also access to the whole configuration object using core.config.root
. Here you should also add your listeners to the core
events, such as core.mock.onChange
, etc.
start(core)
When this method is called, Mocks Server is already started and listening to HTTP requests, and the files watcher is observing for changes too. Here you should start the plugin processes in case there are.
stop(core)
This method is executed when the Mocks Server stop
method is called. Here you should stop all the plugin processes that you started in the start
method.
Plugin id
Plugins must also have an id
static property (usually the plugin name), which is used by Mocks Server in order to provide them some namespaced objects (such as the config
, logger
and alerts
). It is also used for other information purposes.
It is recommended to use camelCase
when defining the plugin id.
Scaffold
Next example shows an empty plugin scaffold that you can use as a starting point:
export default class Plugin {
static get id() {
return "myPluginId";
}
constructor(core) {
// Do your register stuff here
}
register(core) {
// You should omit this method if you already did your register stuff in the constructor
}
init(core) {
// Do your initialization stuff here
}
start(core) {
// Do your start stuff here
}
stop(core) {
// Do your stop stuff here
}
}
Parameters
All plugins methods receive a whole core
instance, but with some methods specifically scoped for the plugin. The core API docs also give details about the methods that are modified when the core is passed to a plugin, but here you have also a summary of the modified methods:
core.alerts
: This property contains a scopedalerts
instance using the pluginid
. It allows to add or remove alerts or alerts namespaces without having conflicts with other plugins or other Mocks Server core elements. Read thecore.alerts
docs to know how to use it, but take into account that in plugins you will receive an alerts subcollection instead of the root alerts object.core.config
: A configuration namespace created specifically for the plugin, using itsid
. Read thecore.config
docs to know how to use it, but take into account that in plugins you will receive a configuration namespace instead of the root configuration object.core.logger
: A namespaced logger using the pluginid
. It allows to easily identify the logs of each plugin and differentiate them from other internal Mocks Server components logs. Read thecore.logger
docs to know how to use it, but take into account that in plugins you will receive a logger namespace instead of the root logger object.
Example
Here you have an example of how a plugin could be defined. It logs the available collections each time they change and allows the user to disable it using an option.
class Plugin {
static get id() {
return "logCollections";
}
constructor(core) {
this._core = core;
this._enabledOption = core.config.addOption({
name: "enabled",
type: "boolean",
description: "Log collections changes",
default: true
});
this._onChangeCollections = this._onChangeCollections.bind(this);
}
init() {
this._enabled = this._enabledOption.value;
this._removeChangeMocksListener = this._core.mock.onChange(this._onChangeCollections);
this._enabledOption.onChange(this._onChangeOption.bind(this));
this._core.logger.debug(`enabled option initial value is ${this._enabled}`);
}
logCollections() {
if (this._enabled && this._started) {
this._core.logger.info(`There are ${this._core.mock.collections.plain.length} collections available`);
}
}
start(core) {
this._started = true;
core.logger.debug("logCollections plugin started");
this.logCollections();
}
stop(core) {
this._started = false;
core.logger.debug("logCollections plugin stopped");
}
_onChangeOption(newValue) {
this._enabled = newValue;
}
_onChangeCollections() {
this.logCollections();
}
}
module.exports = Plugin;
Read the Javascript API chapter for further info about all available Mocks Server core
methods.