The actions are the callable/public methods of the service. The action calling represents a remote-procedure-call (RPC). It has request parameters & returns response, like a HTTP request.
If you have multiple instances of services, the broker will load balancing the request among instances. Read more about balancing.

Call services
To call a service, use the broker.call
method. The broker looks for the service (and a node) which has the given action and call it. The function returns a Promise
.
Syntax
const res = await broker.call(actionName, params, opts); |
The actionName
is a dot-separated string. The first part of it is the service name, while the second part of it represents the action name. So if you have a posts
service with a create
action, you can call it as posts.create
.
The params
is an object which is passed to the action as a part of the Context. The service can access it via ctx.params
. It is optional.
The opts
is an object to set/override some request parameters, e.g.: timeout
, retryCount
. It is optional.
Available calling options:
Name | Type | Default | Description |
---|---|---|---|
timeout |
Number |
null |
Timeout of request in milliseconds. If the request is timed out and you don’t define fallbackResponse , broker will throw a RequestTimeout error. To disable set 0 . If it’s not defined, broker uses the requestTimeout value of broker options. Read more |
retries |
Number |
null |
Count of retry of request. If the request is timed out, broker will try to call again. To disable set 0 . If it’s not defined, broker uses the retryPolicy.retries value of broker options. Read more |
fallbackResponse |
Any |
null |
Returns it, if the request has failed. Read more |
nodeID |
String |
null |
Target nodeID. If set, it will make a direct call to the given node. |
meta |
Object |
null |
Metadata of request. Access it via ctx.meta in actions handlers. It will be transferred & merged at nested calls, as well. |
parentCtx |
Context |
null |
Parent Context instance. |
requestID |
String |
null |
Request ID or correlation ID. It appears in the metrics events. |
Usages
Call without params
broker.call("user.list") |
Call with params
broker.call("user.get", { id: 3 }) |
Call with async/await
const res = await broker.call("user.get", { id: 3 }); |
Call with options
broker.call("user.recommendation", { limit: 5 }, { |
Call with error handling
broker.call("posts.update", { id: 2, title: "Modified post title" }) |
Direct call: get health info from the “node-21” node
broker.call("$node.health", {}, { nodeID: "node-21" }) |
Metadata
Send meta information to services with meta
property. Access it via ctx.meta
in action handlers. Please note at nested calls the meta is merged.
broker.createService({ |
The meta
is sent back to the caller service. Use it to send extra meta information back to the caller. E.g.: send response headers back to API gateway or set resolved logged in user to metadata.
broker.createService({ |
When making internal calls to actions (this.actions.xy()
) you should set parentCtx
to pass meta
data.
Internal calls
broker.createService({ |
Timeout
Timeout can be set in action definition, as well. It overwrites the global broker requestTimeout
option, but not the timeout
in calling options.
Example
// moleculer.config.js |
Calling examples
// It uses the global 3000 timeout |
Streaming
Moleculer supports Node.js streams as request params
and as response. Use it to transfer uploaded file from a gateway or encode/decode or compress/decompress streams.
Examples
Send a file to a service as a stream
const stream = fs.createReadStream(fileName); |
Please note, the params
should be a stream, you cannot add any more variables to the params
. Use the meta
property to transfer additional data.
Receiving a stream in a service
module.exports = { |
Return a stream as response in a service
module.exports = { |
Process received stream on the caller side
const filename = "avatar-123.jpg"; |
AES encode/decode example service
const crypto = require("crypto"); |
Action visibility
The action has a visibility
property to control the visibility & callability of service actions.
Available values:
published
ornull
: public action. It can be called locally, remotely and can be published via API Gatewaypublic
: public action, can be called locally & remotely but not published via API GWprotected
: can be called only locally (from local services)private
: can be called only internally (viathis.actions.xy()
inside service)
Change visibility
module.exports = { |
The default values is
null
(meanspublished
) due to backward compatibility.
Action hooks
Action hooks are pluggable and reusable middleware functions that can be registered before
, after
or on errors
of service actions. A hook is either a Function
or a String
. In case of a String
it must be equal to service’s method name.
Service level declaration
Hooks can be assigned to a specific action (by indicating action name
) or all actions (*
) in service.
Please notice that hook registration order matter as it defines sequence by which hooks are executed. For more information take a look at hook execution order.
Before hooks
const DbService = require("moleculer-db"); |
After & Error hooks
const DbService = require("moleculer-db"); |
Action level declaration
Hooks can be also registered inside action declaration.
Please note that hook registration order matter as it defines sequence by which hooks are executed. For more information take a look at hook execution order.
Before & After hooks
broker.createService({ |
Execution order
It is important to keep in mind that hooks have a specific execution order. This is especially important to remember when multiple hooks are registered at different (service and/or action) levels. Overall, the hooks have the following execution logic:
before
hooks: global (*
)->
service level->
action level.after
hooks: action level->
service level->
global (*
).
Example of a global, service & action level hook execution chain
broker.createService({ |
Output produced by global, service & action level hooks
INFO - Before all hook |
Reusability
The most efficient way of reusing hooks is by declaring them as service methods in a separate file and, later, import them with the mixin mechanism. This way a single hook can be easily shared across multiple actions.
Mixin
module.exports = { |
Use mixin methods in hooks
const MyAuthMixin = require("./my.mixin"); |
Local Storage
The locals
property of Context
object is a simple storage that can be used to store some additional data and pass it to the action handler. locals
property and hooks are a powerful combo:
Setting ctx.locals
in before hook
module.exports = { |
Context
When you call an action, the broker creates a Context
instance which contains all request information and passes it to the action handler as a single argument.
Available properties & methods of Context
:
Name | Type | Description |
---|---|---|
ctx.id |
String |
Context ID |
ctx.broker |
ServiceBroker |
Instance of the broker. |
ctx.action |
Object |
Instance of action definition. |
ctx.nodeID |
String |
The caller or target Node ID. |
ctx.caller |
String |
Action name of the caller. E.g.: v3.myService.myAction |
ctx.requestID |
String |
Request ID. If you make nested-calls, it will be the same ID. |
ctx.parentID |
String |
Parent context ID (in nested-calls). |
ctx.params |
Any |
Request params. Second argument from broker.call . |
ctx.meta |
Any |
Request metadata. It will be also transferred to nested-calls. |
ctx.locals |
Any |
Local data. It will be also transferred to nested-calls. |
ctx.level |
Number |
Request level (in nested-calls). The first level is 1 . |
ctx.call() |
Function |
Make nested-calls. Same arguments like in broker.call |
ctx.emit() |
Function |
Emit an event, same as broker.emit |
ctx.broadcast() |
Function |
Broadcast an event, same as broker.broadcast |
Context tracking
If you want graceful service shutdowns, enable the Context tracking feature in broker options. If you enable it, all services will wait for all running contexts before shutdown.
A timeout value can be defined with shutdownTimeout
broker option. The default values is 5
seconds.
**Enable context tracking & change the timeout value.
const broker = new ServiceBroker({ |
The shutdown timeout can be overwritten by
$shutdownTimeout
property in service settings.
Disable tracking in calling option
broker.call("posts.find", {}, { tracking: false }); |