Skip to main content
Version: Next

Migrating from v2 to v3

danger

If you are already using Mocks Server v1.x you should migrate first from v1.x to v2.x, and then read this chapter to migrate to v3.x.

V3 Motivation

Introducing great breaking changes is something that we always try to avoid on each new major version in order to make as much easy as possible the migration to the users. But the v3.0.0 version introduces a great change in the concept of how the project configuration is structured, and how it can be defined:

This projects tries to be as much modular as possible in order to make easier its evolution and maintenance, and in order to make it flexible and easy to adapt to different use cases. That's why its architecture is based on the concept of plugins. In the case of the configuration, in the prior versions each plugin could add its own configuration options to the "root" level, and this may produce conflicts with other plugins or internal core elements. From this version, we have introduced the concept of "configuration namespaces", so each plugin can define and access to its own options without the risk of conflicts. Apart of this, the configuration mechanism has been improved a lot, and from now it can be defined using even environment variables. Objects or arrays can also be defined in command line arguments or environment variables, etc.

We thought about implementing a backward compatibility mechanism with the v2.x configuration, or even an automated migration process, but, after analyzing it deeply, we noticed that the effort of doing it, and the possible bugs that it may cause don't worth, taking into account that the configuration should not be hard to change by the users theirself. Anyway, in this chapter you'll find a complete equivalence table between old and new options to make it easier.

About the plugins API, it has been changed also because the number of arguments received by them was growing. So, from now everything is received in a single object. This maybe would make migrating to this version harder, but it will improve the migration process to next major versions, as well as it will make easier to us to provide backward compatibility mechanisms in the future.

As a summary, the version 3 improves the configuration mechanism and other legacy technical debts in order to make easier to add new awesome features to the project in the future, so we apologize for the breaking changes and we hope that the migration job will worth. 🙂

Changes summary

The main changes from v2.x to v3.x are:

  • Backward compatibility with v1.x has been removed. All v1.x legacy methods and routes have been removed from all packages.
  • Configuration has been completely modified.
    • Namespaces have been added in order to keep the configuration of each component and plugin isolated from the rest.
    • Now it supports different configuration file names and formats, such as .yaml, etc. Cosmiconfig is used under the hood to provide this feature.
    • The way in which command line arguments are defined has also changed due to namespaces.
    • Defining configuration using environment variables now is supported also.
  • Methods for creating or reading settings programmatically (from the plugins, for example) have completely changed. Read the configuration API section bellow for further info.
  • The Core object in the @mocks-server/core package now is exported as default. This only affects to users using the programmatic API.
  • Some methods of the Core API have been removed. Most of them are related to the configuration. See programmatic API below for further info.
  • Arguments received by the plugins have changed. Read plugins below for further info.
  • Drop support for Node.js 12.x.

Node.js version

Support for Node.js version 12.x has been removed. From now, packages tests are not executed any more using that version.

Configuration

As mentioned, the configuration structure have been completely changed. You can read the updated configuration docs for further info. Now options can be defined using different file names and formats, process arguments and even environment variables.

tip

TIP: You can rename your current mocks.config.js file into old_mocks.config.js file. Then start the server and a new configuration scaffold file will be created, then it will be easier to move your current values to the new configuration file.

In order to adapt your current v2.x configuration to v3.x, here you have an equivalence table between old and new options, including command line arguments and new environment variables:

Old optionNew optionOld argumentNew argumentNew env var
pathfiles.path--path--files.pathMOCKS_FILES_PATH
portserver.port--port--server.portMOCKS_SERVER_PORT
hostserver.host--host--server.hostMOCKS_SERVER_HOST
loglog--log--logMOCKS_LOG
watchfiles.watch--no-watch--no-files.watchMOCKS_FILES_WATCH
mockmocks.selected--mock--mocks.selectedMOCKS_MOCKS_SELECTED
delaymocks.delay--delay--mocks.delayMOCKS_MOCKS_DELAY
corsserver.cors.enabled--no-cors--no-server.cors.enabledMOCKS_SERVER_CORS_ENABLED
corsPreFlight*server.cors.options--no-corsPreFlight--server.cors.optionsMOCKS_SERVER_CORS_OPTIONS
cliplugins.inquirerCli.enabled--no-cli--no-plugins.inquirerCli.enabledMOCKS_PLUGINS_INQUIRER_CLI_ENABLED
adminApiPathplugins.adminApi.path--adminApiPath--plugins.adminApi.pathMOCKS_PLUGINS_ADMIN_API_PATH
babelRegisterfiles.babelRegister.enabled---files.babelRegister.enabledMOCKS_FILES_BABEL_REGISTER_ENABLED
babelRegisterOptionsfiles.babelRegister.options---files.babelRegister.optionsMOCKS_FILES_BABEL_REGISTER_OPTIONS
pluginsplugins.register---
addPluginsplugins.register---
addRouteHandlersrouteHandlers---
configFileconfig.fileSearchPlaces (Array)---config.fileSearchPlacesMOCKS_CONFIG_FILE_SEARCH_PLACES
onlyProgrammaticOptions----
disableCommandLineArgumentsconfig.readArguments--MOCKS_CONFIG_READ_ARGUMENTS
disableConfigFileconfig.readFile---no-config.readFileMOCKS_CONFIG_READ_FILE
-config.readEnvironment---
note
  • The corsPreFlight option now has to be defined directly as an option for the cors middleware, which can be an object with any option to it. So, now it becomes: server: { cors: { options : { preflightContinue: true }}}, or --server.cors.options='{"corsPreFlight":true}' in command line arguments.

Examples

So, based on the table above, a typical v2 configuration file like the next one:

module.exports = {
options: {
mock: "base",
cli: false,
port: 3200,
},
};

It would become:

module.exports = {
mocks: {
selected: "base",
},
plugins: {
inquirerCli: {
enabled: false,
},
},
server: {
port: 3200,
},
};
danger

Note that the configuration structure has changed also in all of the plugins, so the equivalence table above has to be taking into account also when making HTTP requests to the plugin-admin-api, for example.

Plugins

In order to make compatible your plugins with the v3 version, you have to:

  • Add an id property to them (an static property in the case of Class plugins). This allows the core to create an appropriate namespace for the plugins and pass to them the correspondent config and alerts objects.
  • Change the Core API deprecated methods for creating and reading settings if you were using them by the new ones. Read the configuration API section bellow for further info.
  • Change the arguments that they receive in the constructor, register, init, start and stop methods. Now they will receive:
    • 3.1: A single argument as an object containing all needed methods and properties Previously, the core API was received as first argument, and from now it is received as a { core } property in the first argument.
    • >=3.2: A Mocks Server 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.

So, a plugin that in v2 was defined as:

class Plugin {
constructor(core, { loadMocks, loadRoutes, addAlert, removeAlerts }) {
// Do your stuff here
}

register(core, { loadMocks, loadRoutes, addAlert, removeAlerts }) {
// Do your stuff here
}

init(core, { loadMocks, loadRoutes, addAlert, removeAlerts }) {
// Do your stuff here
}

start(core, { loadMocks, loadRoutes, addAlert, removeAlerts }) {
// Do your stuff here
}

stop(core, { loadMocks, loadRoutes, addAlert, removeAlerts }) {
// Do your stuff here
}

get displayName() {
return "myPlugin";
}
}

In v3.1 had to be defined as in the next example, but you shouldn't use the core property, because it will be removed in the next major version. Better use the v3.2 example, which will be fully compatible with v4.

class Plugin {
static id = "myPlugin";

constructor({ core, loadMocks, loadRoutes, alerts, config }) {
// Do your stuff here
}
}

And in any version equal or greater than v3.2 it has to be defined as:

class Plugin {
static id = "myPlugin";

constructor({ onChangeMocks, onChangeAlerts, logger, loadMocks, loadRoutes, alerts, config }) {
// Here you receive all of the core API methods in one single argument
// The parameter is destructured only for example purpose
}

register(core) {
// Do your stuff here
}

init(core) {
// Do your stuff here
}

start(core) {
// Do your stuff here
}

stop(core) {
// Do your stuff here
}
}
note

The old addAlert and removeAlerts methods can still be used in v3, but they are considered deprecated since v3.1.0 and will be removed in next major version. The core property added in v3.1 can be still used in any v3.x version, but it will be also removed in v4. Any usage of these methods would produce an alert. Read the updated documentation about creating plugins for further info about how to use them.

Configuration API

As a result of the programmatic API changes, old methods for creating or reading settings are not available any more, such as core.addSetting, core.settings.get, core.settings.set or core.lowLevelConfig. Now you can create, read, or listen to configuration changes using the core.config object, or using the config object received in plugins, which is already namespaced with each plugin name. Here you have a brief example of how you can migrate from one system to another. For further information, you should read the updated documentation about creating plugins.

If you were creating or reading settings like this in v2:

class Plugin {
constructor(core) {
this._core = core;
this._core.addSetting({
name: "myOption",
type: "string",
});
}

start() {
this._core.tracer.info(`Current value of my option is ${this._core.settings.get("myOption")}`);
this._core.onChangeSettings(this._onChangeSettings.bind(this));
}

_onChangeSettings(changedSettings) {
this._core.tracer.info(`Changed settings: ${JSON.stringify(changedSettings)}`);
}

get displayName() {
return "myPlugin";
}
}

Now you have to do it like this in >=3.2:

class Plugin {
static id = "myPlugin";

constructor(core) {
this._core = core;
this._myOption = core.config.addOption({
name: "myOption",
type: "string",
});
}

start() {
this._core.logger.info(`Current value of my option is ${this._myOption.value}`);
this._myOption.onChange(this._onChangeMyOption.bind(this));
}

_onChangeMyOption(newValue) {
this._core.logger.info(`My option changed to: ${newValue}`);
}
}
info

And remember, from now, the user must define the options for your plugin under the namespace of your plugin id: --plugins.myPlugin.myOption=foo

Importing @mocks-server/core

The Core object in the @mocks-server/core package now is exported as default. So, if you were importing v2.x as in:

const { Core } = require("@mocks-server/core"); // Error in v3.x

Now you should import it like:

const Core = require("@mocks-server/core"); // Works in v3.x

Programmatic API

Some of the next methods were added to v2.x in order to provide easy backward compatibility with v1.x. All of them have been removed in v3.x, so, if you started using v2.x, you may have not used any legacy method, and updating to v3.x shouldn't produce any breaking change.

In case you have not still migrated completely to v2.x, please read the "Migrating from v1 to v2" guide. Once you have migrated to v2.x, next changes won't affect to you. Anyway, here is the complete list of methods removed from all @mocks-server packages in v3.x:

@mocks-server/core

  • The Core object now is export as default.
  • The Behavior object has been removed and it is not exported any more.
  • The addFixturesHandler and onChangeLegacyMocks have been removed from the Core API.
  • The behaviors and fixtures getters have been removed from the Core API.
  • The pathLegacy, behavior and watchLegacy options are not supported any more.
  • The legacy --behavior command line argument has been removed.
  • The load:mocks:legacy and change:mocks:legacy events are not emitted any more.
  • The addSetting method has been removed from the Core API.. Now plugins should add their configuration options using the config object that they receive. The global config object is also available in the core API.
  • The onChangeSettings method has been removed from the Core API.. Now listeners must be added using the config object.
  • The settings getter has been removed from the Core API.. Instead of it, the config getter must be used, but note that its API have changed too.
  • The lowLevelConfig getter has been removed from the Core API.. The concept of lowLevelConfig is not used any more, because now there are configuration namespaces, and everything can be configured at any lifecycle time. The config object must be used instead.

@mocks-server/main

  • Export Core as default export.
  • The Behavior object has been removed and it is not exported any more.

@mocks-server/cypress-commands

  • The mocksSetBehavior command has been removed.

@mocks-server/plugin-inquirer-cli

  • Remove support for v1 legacy mode options.

@mocks-server/plugin-admin-api

  • All legacy APIs under the /legacy path have been removed.
  • The adminApiDeprecatedPaths option is not supported any more.

@mocks-server/admin-api-paths

  • Removed LEGACY, BEHAVIORS and FIXTURES constants.

@mocks-server/admin-api-client-data-provider

  • Removed behaviors, behavior, behaviorsModel, fixtures, fixture, fixtureModel legacy objects and all of its methods.

@mocks-server/admin-api-client

  • Removed legacy methods readBehaviors, readBehavior, readFixtures and readFixture.