@betit/orion
Version:
Pluggable microservice framework
113 lines (112 loc) • 3.5 kB
JavaScript
;
const codec_1 = require('../codec');
const transport_1 = require('../transport');
const utils_1 = require('../utils');
const debug = utils_1.debugLog('orion:client');
/**
* Provides an interface to make requests to services.
*/
class Client {
/**
* Create new client.
*/
constructor(options) {
this.options = options;
this.options = Object.assign({
callTimeout: 10000
}, options);
this.codec = this.options.codec || new codec_1.DefaultBinaryCodec();
this.transport = this.options.transport || new transport_1.DefaultTransport();
}
/**
* Publish to a topic.
* @param {any} topic
* @param {Object} message
*/
emit(topic, message) {
debug('emit:', topic);
this.transport.publish(topic, this.codec.encode(message));
}
/**
* Call service method.
* @param {Object} request
* @param {Object} [params]
* @param {Function} callback
*/
call(request, params, callback) {
// supports method call without params
if (typeof request === 'string') {
request = {
path: request
};
}
if (arguments.length === 2) {
if (request.params === undefined) {
request.params = null;
}
if (typeof params === 'function') {
callback = params;
}
else {
request.params = params || null;
}
}
else if (arguments.length === 3) {
request.params = params;
}
if (!callback) {
callback = function () { };
}
let route = request.path;
// services registered with names like `service.method`
// but we support `/service/method` style calls as well
// hence we need to "normalize" the route here.
route = route.replace(/\//gi, '.');
if (route.startsWith('.')) {
route = route.substring(1);
}
if (!route) {
return callback(new Error('Invalid request path'));
}
if (this.options.service) {
route = `${this.options.service}.${route}`;
}
debug('calling:', route);
const req = this.codec.encode(request);
debug('sending request:', request);
this.transport.request(route, req, res => {
if (res instanceof Error) {
callback(res);
}
else {
const response = this.codec.decode(res);
debug('got response:', response);
callback(response.err, response.res);
}
}, this.getCallTimeout(request.path, request.params));
}
getCallTimeout(path, params) {
let options = this.options || {};
let paramsCallTimeout = params && params.callTimeout;
let specificCallTimeout = options.callTimeouts && options.callTimeouts[path];
return paramsCallTimeout || specificCallTimeout || options.callTimeout;
}
/**
* Close underlying transport connection.
*/
close() {
debug('close');
this.transport.close();
}
/**
* Connection closed handler
* @param {Function} callback
*/
onClose(callback) {
this.transport.onClose(() => {
callback();
});
}
}
Object.defineProperty(exports, "__esModule", { value: true });
exports.default = Client;