github moleculerjs/moleculer v0.9.0

latest releases: v0.15.0-beta1, v0.14.33, v0.14.32...
6 years ago

Breaking changes

Namespace support, removed prefix options #57

The broker has a new namespace option to segment your services. For example, you are running development & production services (or more production services) on the same transporter. If you are using different namespace you can avoid collisions between different environments.

You can reach it in your services as this.broker.namespace.

Thereupon the prefix option in transporters & cachers is removed.

Example

const broker = new ServiceBroker({
    logger: console,
    namespace: "DEV",
    transporter: "NATS",
    cacher: "Redis"
});

In this case the transporter & cacher prefix will be MOL-DEV.

Renamed internal service settings

The useVersionPrefix is renamed to $noVersionPrefix. The serviceNamePrefix is renamed to $noServiceNamePrefix. Both settings logical state is changed.
The cache setting is renamed to $cache.

Migration guide

Before

broker.createService({
    name: "test",
    settings: {
        useVersionPrefix: false,
        serviceNamePrefix: false,
        cache: true
    }
});

After

broker.createService({
    name: "test",
    settings: {
        $noVersionPrefix: true,
        $noServiceNamePrefix: true,
        $cache: true
    }
});

Changed versioned action names #58

Based on #58 if service version is a String, the version in action names won't be prefixed with v, expect if it is a Number.

Example

broker.createService({
    name: "test",
    version: 3,
    actions: {
        hello(ctx) {}
    }
});
broker.call("v3.test.hello");

broker.createService({
    name: "test",
    version: "staging",
    actions: {
        hello(ctx) {}
    }
});
broker.call("staging.test.hello");

Module log level configuration is removed

The module log level is not supported. The logLevel option can be only String. It is used if the logger is the console. In case of external loggers you have to handle log levels.

New

Better logging #61

The whole Moleculer logger is rewritten. It supports better the external loggers. The built-in log message format is also changed.

Built-in console logger

const broker = createBroker({ 
    logger: console, 
    logLevel: "info"
});

New console output:
image

With custom logFormatter

const broker = new ServiceBroker({ 
    logger: console, 
    logFormatter(level, args, bindings) {
        return level.toUpperCase() + " " + bindings.nodeID + ": " + args.join(" ");
    }
});
broker.logger.warn("Warn message");
broker.logger.error("Error message");

Output:

WARN dev-pc: Warn message
ERROR dev-pc: Error message

External loggers

Pino

const pino = require("pino")({ level: "info" });
const broker = new ServiceBroker({ 
    logger: bindings => pino.child(bindings)
});

Sample output:
image

Bunyan

const bunyan = require("bunyan");
const logger = bunyan.createLogger({ name: "moleculer", level: "info" });
const broker = new ServiceBroker({ 
    logger: bindings => logger.child(bindings)
});

Sample output:
image

Winston

const broker = new ServiceBroker({ 
    logger: bindings => new winston.Logger({
        transports: [
            new (winston.transports.Console)({
                timestamp: true,
                colorize: true,
                prettyPrint: true
            })
        ]
    })
});

Winston context

const WinstonContext = require("winston-context");
const winston = require("winston");
const broker = createBroker({ 
    logger: bindings => new WinstonContext(winston, "", bindings)
});

Please note! Some external loggers have not trace & fatal log methods (e.g.: winston). In this case you have to extend your logger.

const WinstonContext = require("winston-context");
const winston = require("winston");
const { extend } = require("moleculer").Logger;
const broker = createBroker({ 
    logger: bindings => extend(new WinstonContext(winston, "", bindings))
});

The bindings contains the following properties:

  • ns - namespace
  • nodeID - nodeID
  • mod - type of core module: broker, cacher, transit, transporter
  • svc - service name
  • ver - service version

Please avoid to use these property names when you log an Object. For example: the broker.logger.error({ mod: "peanut" }) overrides the original mod value!

Dynamic service load & destroy

Available to load & destroy services after the broker started. For example you can hot-reload your services in runtime. The remote nodes will be notified about changes and the broker will emit a services.changed event locally.

Example

broker.start().then(() => {

    setTimeout(() => {
        // Create a new service after 5s
        broker.createService({
            name: "math",
            actions: {
                add(ctx) {
                    return Number(ctx.params.a) + Number(ctx.params.b);
                },
            }
        });

    }, 5000);

    setTimeout(() => {
        // Destroy a created service after 10s
        let svc = broker.getService("math");
        broker.destroyService(svc);

    }, 10000);

});

Multiple service calls #31

With broker.mcall method you can call multiple actions (in parallel).

Example with Array

broker.mcall([
    { action: "posts.find", params: {limit: 5, offset: 0}, options: { timeout: 500 } },
    { action: "users.find", params: {limit: 5, sort: "username"} }
]).then(results => {
    let posts = results[0];
    let users = results[1];
})

Example with Object

broker.mcall({
    posts: { action: "posts.find", params: {limit: 5, offset: 0}, options: { timeout: 500 } },
    users: { action: "users.find", params: {limit: 5, sort: "username"} }
}).then(results => {
    let posts = results.posts;
    let users = results.users;
})

Don't miss a new moleculer release

NewReleases is sending notifications on new releases.