microX
Usage
microX module provides one simple constructor, the Service
constructor.
The returned instance encapsulates all the required functionally to build a fully functional service.
Initialization
const microx = require('microx')
let configuration = {
name: 'sample service',
port: 8080,
host: '127.0.0.1'
}
let serviceInstance = microx(configuration);
serviceInstance.start()
Create an configuration object, you can use a simple object or the Service.ServiceConfiguration
constructor to validate the configuration object and setup default values.
To start your micro-service, call the start
method.
You can stop the service, by calling the stop
method.
Events
The Service
constructor extends the EventsEmitter
constructor. The following events are emitted by the Service
:
service start
Emitted when the service start method finished all the required processing and the service is ready to accept requests
service stopped
Emitted when the service stop method finished all the required processing and the service is no longer able to accept new requests
service ping
Emitted when another service has pinged the service The event gets the pinging service meta object
call service error
Emitted when the service called another service and an error occurred
call unknown service
Emitted when the service called a service that it does not know its location
rpc server started
Emitted when the RPC HTTP server started listening
rpc server error
Emitted when the RPC HTTP server got an error
rpc server stopped
Emitted when the RPC HTTP server stopped listening
service remove error
Emitted when the service failed to send REMOVE multicast The event gets the error object
service remove sent
Emitted when the service sent REMOVE multicast
service removed
Emitted when the service got a REMOVE multicast from another service and removed that service from the locations map The event gets the removed service meta object
service message
Emitted when the service got a multicast message from another service The event gets the message object
services clean
Emitted when the service has finished a locations & versions maps cleaning to remove irrelevant services
service ping interval started
Emitted when the service started his pinging interval timer The event gets the interval value
service ping interval stopped
Emitted when the service stopped his pinging interval timer
service ping sent
Emitted when the service sent a PING multicast message The event gets the service meta object
service ping error
Emitted when the service failed to send a PING multicast message The event gets the error object
Methods
The service instance exposes the following methods:
provide
The provide
method accepts 2 arguments:
- method - the name of the method
- handler - the method handler function (see more below)
The provide
method registers the method handler to the method name, so another service that will call this method will trigger the execution of the registered handler.
mockup
The mockup
method accepts 3 arguments:
- service - the full name of the service to mockup (including version, otherwise will default to @1.0.0)
- method - the name of the method to mockup
- handler - the method handler function (see more below)
The mockup
method registers a mockup method handle. Calling the service-method combination will result in a local call to the mockup method instead of the real service.
broadcast
The broadcast
method accepts 2 arguments:
- event - the event name (the service name will be added automatically as a prefix)
- data - a payload of data to attach to the event, this data will be received by all services that listens to it
Broadcast an event to other services. The broadcasting service will not receive the event, but all other services that listens on the event will receive the event.
start
Start the service RPC server and listen to incoming requests. Emit a started
event to other services to add this instance or update the last appearance of the instance in the services map.
stop
Stop the service RPC server and publish a stopped
event to other service to remove this instance from their services map.
on
Register an event listener for internal events of the service (as listed above)
call
Call another service
The call
method accepts 2 arguments:
- service - the full name of the service, including version in the format of [name]@[version]. If the version is not specified, it will automatically be the highest version known in the service map.
- method - the name of the method
- data - data to send to the method
- parentMessage - if the call is triggered from another method handler, pass the parent message object to keep track of the message ID.
The method returns a Promise that will be resolved if the method handler of the called method will reply without an error, or rejected if the called method replied with an error.
httpRequest
A simple wrapper for request
module. Used to call any third party HTTP based API.
The httpRequest
method accepts a single argument, the request
module options object. See request
module documentation for details.
The method returns a Promise that will be rejected if the request
callback returned an error and resolved with the response if no error occurred.
getServices
Get an array of known services (service map)
getEventsQueues
Get the list of all pending events
Method Handler
Each time a method is defined in a service, it should include a method handler function. The method handler function will get executed when another service performed a call to the method.
The method handler will get 3 arguments:
Message
The incoming message object. The message object includes the data sent from the calling service and some extra meta data. See Message object definition.
Reply function
The reply function is used to reply to the calling service. The reply function is a common (err, data) callback, where the first argument is the Error object if an error occurred, or null if everything is OK and the second object is the data to reply with in case of success.
Service instance
The current service instance is passed as the third argument to provide the developer with an option to perform service method calls from the handler such as broadcasting an event, calling another service method etc.
serviceInstance.provide('myMethod', handler)
function handler(msg, reply, service) {
console.log(msg.data)
service.broadcast('myMethodHandlerCalled', msg.data)
reply(null, {status: 'OK'})
}
Event Handler
Each time an event listener is defined in a service, it should include an event handler function. The event handler function will get executed when another service broadcast an event that match the event that is listened to.
The event handler will get 2 arguments:
Event
The event object that includes the data the was sent in the event broadcast.
Service instance
The current service instance is passed as the second argument to provide the developer with an option to perform service method calls from the handler such as broadcasting an event, calling another service method etc.
serviceInstance.onEvent('myMethodHandlerCalled', eHandler)
function eHandler(event, service) {
console.log(event.data)
// Use service if needed
}
Testing using HTTP client
Each service exposes his methods via an HTTP server. If you wish to call a service method without a second service instance, you can use any simple HTTP client that can perform POST requests.
The URL is the service URL (with port if required), and the path if the method name.
Perform a POST request with a JSON encoded object as the body (don’t forget the Content-Type
header, set it to application/json
), and it will perform a call to the method.
For example:
const Service = require('microx')
let configuration = new Service.ServiceConfiguration({
name: 'math',
port: 8080,
host: '127.0.0.1'
})
let serviceInstance = new Service(configuration);
serviceInstance.provide('sum', sum)
serviceInstance.start()
function sum(msg, reply) {
if (!Number.isInteger(msg.data.x) || !Number.isInteger(msg.data.y)) {
return reply(new Error('Invalid X or Y values'))
}
reply(null, {sum: msg.data.x + msg.data.y})
}
To test this service, you can POST the following JSON:
{
"x": 1,
"y": 2
}
With the header Content-Type: application/json
to the URL: http://127.0.0.1:8080/sum
The response will be a JSON encoded Message object. For example:
{
"id": "cdbb3bf36c2343429870907b0e3fde47",
"data": {
"sum": 3
},
"headers": {
"accept": "*/*",
"cache-control": "no-cache",
"content-type": "application/json",
"content-length": "22",
"host": "localhost:8080",
"connection": "Keep-Alive",
"user-agent": "Apache-HttpClient/4.5.2 (Java/1.8.0_112-release)",
"accept-encoding": "gzip,deflate"
},
"time": 1502478245291,
"from": "math@1.0.0"
}
Objects
Message
A message between 2 services.
The object fields:
- id - a unique ID of the message (UUID V4). If the request includes an header
X-Request-ID
, the value will be extracted from that header. - data - the message payload data
- headers - the message headers. Will automatically inherit the request headers.
- time - a milliseconds UNIX timestamp of the message
- from - the name and version of the service that created the message
Event
An event object is created every time an event is broadcast.
The object fields:
- id - a unique event ID of the event (UUID V4)
- name - the name of the event. The name automatically includes the service name as a prefix
- data - the event payload data
- meta - the event meta data object.
Event Meta
A meta data that is attached to each Event object.
The object fields:
- emitter - the name and version of the emitting service
- emitterId - the unique ID of the service instance that emitted the event
- time - a milliseconds UNIX timestamp of the event
Service Meta
A meta data attached to the service instance. Available via the meta
property.
The object fields:
- id - a unique event ID of the service instance (UUID V4)
- versionName - a full name with the version attached by
@
- name - the name of the service
- version - the version of the service
- port - the port the service listens on
- host - the host that the service publishes to the other services to locate it at
- url - the complete URL of the service
- secure - is the service exposed via secure HTTPS connection
- ttl - how long (in seconds) the service is considered alive by other service - after each
ttl
seconds the service will publish itself again to the other services