Events
Steedos has a built-in event bus to support Event-driven architecture and to send events to local and remote services.
Please note that built-in events are fire-and-forget meaning that if the service is offline, the event will be lost.
Balanced events
The event listeners are arranged to logical groups. It means that only one listener is triggered in every group.
Example: you have 2 main services:
billing&payment. Both subscribe to theuser.purchasedevent. You start 2 instances ofbillingservice and 2 instances ofpaymentservice. When you emit theuser.purchasedevent, only onebillingand onepaymentservice instance will receive the event.

Example
module.exports = {
name: "@steedos-labs/project",
events: {
"user.purchased": {
handler(ctx) {
console.log("Payload:", ctx.params);
console.log("Sender:", ctx.nodeID);
console.log("Metadata:", ctx.meta);
console.log("The called event name:", ctx.eventName);
}
}
}
}
Emit balanced events
Send balanced events with broker.emit function. The first parameter is the name of the event, the second parameter is the payload.
To send multiple values, wrap them into an Object.
// The `user` will be serialized to transportation.
broker.emit("user.purchased", config);
Broadcast event
The broadcast event is sent to all available local & remote services. It is not balanced, all service instances will receive it.

Send broadcast events with broker.broadcast method.
broker.broadcast("user.updated", config);
Subscribe to events
Event context is useful if you are using event-driven architecture and want to trace your events. The Event Context is very similar to Action Context, except for a few new event related properties.
module.exports = {
name: "@steedos-labs/project",
events: {
"@space_users.inserted"(ctx) {
console.log("Payload:", ctx.params);
console.log("Sender:", ctx.nodeID);
console.log("Metadata:", ctx.meta);
console.log("The called event name:", ctx.eventName);
ctx.emit("users.changed", { data: ctx.params.doc });
},
"@space_users.deleted": {
handler(ctx) {
console.log(`${this.broker.nodeID}:${this.fullName}: Event '${ctx.eventName}' received. Payload:`, ctx.params, ctx.meta);
}
}
}
};
Subscribe to events in 'events' property of services. Use of wildcards (?, *, **) is available in event names.
module.exports = {
events: {
// Subscribe to `user.created` event
"@space_users.inserted"(ctx) {
console.log("User created:", ctx.params);
},
// Subscribe to all `user` events, e.g. "user.created", or "user.removed"
"@space_users.*"(ctx) {
console.log("User event:", ctx.params);
}
// Subscribe to every events
// Legacy event handler signature with context
"**"(payload, sender, event, ctx) {
console.log(`Event '${event}' received from ${sender} node:`, payload);
}
}
}
Event parameter validation
Similar to action parameter validation, the event parameter validation is supported.
Like in action definition, you should define params in event definition and the built-in Validator validates the parameters in events.
// mailer.service.js
module.exports = {
name: "@steedos-labs/mail",
events: {
"send.mail": {
// Validation schema
params: {
from: "string|optional",
to: "email",
subject: "string"
},
handler(ctx) {
this.logger.info("Event received, parameters OK!", ctx.params);
}
}
}
};
The validation errors are not sent back to the caller, they are logged or you can catch them with global error handler.