Discussion about how Moleculer can support ES6 classes as a Service.
"use strict";
module.exports = {
name: "greeter",
version: "v2",
meta: {
scalable: true
},
dependencies: [
"auth",
"users"
],
settings: {
upperCase: true
},
actions: {
hello() {
return "Hello Moleculer";
},
welcome: {
cache: {
keys: ["name"]
},
params: {
name: "string"
},
handler(ctx) {
return this.sayWelcome(ctx.params.name);
}
}
},
events: {
"user.created"(user) {
this.broker.call("mail.send", { user });
}
},
methods: {
sayWelcome(name) {
this.logger.debug("Say hello to", name);
return `Welcome, ${this.settings.upperCase ? name.toUpperCase() : name}`;
}
},
created() {
this.logger.info("Service created.");
},
started() {
this.logger.info("Service started.");
},
stopped() {
this.logger.info("Service stopped.");
}
};
Any idea?
In the next version it will work:
const Service = require("moleculer").Service;
class GreeterService extends Service {
constructor(broker) {
super(broker);
this._processSchema({
name: "greeter",
version: "v2",
meta: {
scalable: true
},
dependencies: [
"auth",
"users"
],
settings: {
upperCase: true
},
actions: {
hello: this.hello,
welcome: {
cache: {
keys: ["name"]
},
params: {
name: "string"
},
handler: this.welcome
}
},
events: {
"user.created": this.userCreated
},
created: this.serviceCreated,
started: this.serviceStarted,
stopped: this.serviceStopped,
});
}
// Action handler
hello() {
return "Hello Moleculer";
}
// Action handler
welcome(ctx) {
return this.sayWelcome(ctx.params.name);
}
// Private method
sayWelcome(name) {
this.logger.info("Say hello to", name);
return `Welcome, ${this.settings.upperCase ? name.toUpperCase() : name}`;
}
// Event handler
userCreated(user) {
this.broker.call("mail.send", { user });
}
serviceCreated() {
this.logger.info("ES6 Service created.");
}
serviceStarted() {
this.logger.info("ES6 Service started.");
}
serviceStopped() {
this.logger.info("ES6 Service stopped.");
}
}
module.exports = GreeterService;
Have you considered using decorators? This could simplify the structure of the class as the constructor would not hold the definition of the service, it would be within the class.
https://medium.com/google-developers/exploring-es7-decorators-76ecb65fb841
const Service = require("moleculer").Service;
const Decorators = require("moleculer").Decorators;
const serviceVersion = Decorators.serviceVersion;
const serviceName = Decorators.serviceName;
const meta = Decorators.meta;
const dependencies = Decorators.dependencies;
const serviceSettings = Decorators.serviceSettings;
const action = Decorators.action;
const cache = Decorators.cache;
const params = Decorators.params;
const event = Decorators.event;
const lifeCycleEvent = Decorators.lifeCycleEvent;
@serviceVersion("v2")
@serviceName("greeter")
@meta({ scalable: true })
@dependencies(["auth", "users"])
@serviceSettings({ upperCase: true })
class GreeterService extends Service {
constructor(broker) {
super(broker);
}
// Action handler
@action("hello")
hello() {
return "Hello Moleculer";
}
// Action handler
@action("welcome")
@cache({ keys: ["name"] })
@params({ name: "string" })
welcome(ctx) {
return this.sayWelcome(ctx.params.name);
}
// Private method
sayWelcome(name) {
this.logger.info("Say hello to", name);
return `Welcome, ${this.settings.upperCase ? name.toUpperCase() : name}`;
}
// Event handler
@event("user.created")
userCreated(user) {
this.broker.call("mail.send", { user });
}
@lifeCycleEvent("created")
serviceCreated() {
this.logger.info("ES6 Service created.");
}
@lifeCycleEvent("started")
serviceStarted() {
this.logger.info("ES6 Service started.");
}
@lifeCycleEvent("stopped")
serviceStopped() {
this.logger.info("ES6 Service stopped.");
}
}
module.exports = GreeterService;
@rmccallum81 We already have decorators :D
Most helpful comment
@rmccallum81 We already have decorators :D