Security News
Fluent Assertions Faces Backlash After Abandoning Open Source Licensing
Fluent Assertions is facing backlash after dropping the Apache license for a commercial model, leaving users blindsided and questioning contributor rights.
nats-hemera
Advanced tools
A Node.js microservices toolkit for the NATS messaging system
Hemera is a small wrapper around the nats driver. We want to provide a toolkit to develop microservices in an easy and powerful way. We use bloom filters to provide a pattern matching RPC style. You don't have to worry about the transport. NATS is powerful.
With Hemera you have the best of both worlds. Efficient pattern matching to have the most flexibility in defining your RPC's.
It doesn't matter where your server or client lives. You can add the same add
as many as you want on different hosts to ensure maximal availability. Thanks to the Request Reply pattern you can work with that as if you do a normal http request. The only dependency you have is a single binary of 7MB. Mind your own business NATS do the rest for you:
topic:auth:germany
+ Hemera = Pattern-driven micro services.
We use the Request Reply concept to realize this toolkit. Request Reply
npm i nats-hemera
'use strict';
const Hemera = require('hemera');
const nats = require('nats').connect(authUrl);
const hemera = new Hemera(nats, { logLevel: 'info' });
hemera.ready(() => {
hemera.add({ topic: 'math', cmd: 'add' }, (resp, cb) => {
cb(null, resp.a + resp.b);
});
hemera.add({ topic: 'email', cmd: 'send' }, (resp, cb) => {
cb();
})
hemera.act({ topic: 'math', cmd: 'add', a: 1, b: 2, timeout$: 5000 }, (err, resp) => {
console.log('Result', resp);
});
//Without callback
hemera.act({ topic: 'email', cmd: 'send', email: 'foobar@mail.com', msg: 'Hi' });
});
hemera.add({ topic: 'math', cmd: 'add' }, (resp, cb) => {
cb(null, resp.a + resp.b);
});
hemera.act({ topic: 'math', cmd: 'add', a: 1, b: 1 }, (err, resp) => {
console.log(resp); //2
});
A match happens when all properties of the added pattern matches with the one in the passed obj.
hemera.add({ topic: 'math', cmd: 'add' }, (resp, cb) => {
cb(resp.a + resp.b)
});
hemera.act({ topic: 'math', cmd: 'add', a: 1, b: 1 });
hemera.add({ topic: 'math', cmd: 'add', foo: 'bar' }, (resp, cb) => {
cb(resp.a + resp.b)
});
hemera.act({ topic: 'math', cmd: 'add', a: 1, b: 1 });
hemera.add({ topic: 'math', cmd: 'add' }, (resp, cb) => {
cb(new CustomError('Invalid operation'));
});
hemera.act({ topic: 'math', cmd: 'add', a: 1, b: 1 }, (err, resp) => {
err instanceOf CustomError // true
});
hemera.act({ topic: 'math', cmd: 'add', a: 1, b: 1 }, (err, resp) => {
err instanceOf TimeoutError // true
});
Fatal errors will crash your server. You should implement a gracefully shutdown and use a process watcher like PM2 to come back in a clear state. Optional you can disable this behaviour by crashOnFatal: false
hemera.act({ topic: 'math', cmd: 'add', a: 1, b: 1 }, (err, resp) => {
throw new Error('Upps');
});
hemera.add({ topic: 'math', cmd: 'add' }, (resp, cb) => {
err instanceOf FatalError // true
});
const hemera = new Hemera(nats, { logLevel: 'info' });
hemera.events.on('error', ...)
hemera.events.on('disconnect', ...)
hemera.events.on('connect', ...)
//see NATS driver for more events
hemera.act({ topic: 'math', cmd: 'add', a: 1, b: 1, timeout$: 5000 }, (err, resp) => {
});
this
If you want to transfer metadata to a service you can use the meta$
property before sending. It will be passed in all nested act
.
E.g you can add a JWT token as metadata to express if your action is legitimate.
hemera.add({ topic: 'math', cmd: 'add' }, function (resp, cb) {
//Access to metadata
let meta = resp.meta$
cb(null, resp.a + resp.b);
});
Will set the metadata only for this act
and all nested act
hemera.act({ topic: 'math', cmd: 'add', a: 1, b: 1, meta$: { a: 'test' } }, function (err, resp) {
this.act({ topic: 'math', cmd: 'add', a: 1, b: 5 });
});
Will set the metadata on all act
hemera.meta$.token = 'ABC1234'
hemera.act({ topic: 'math', cmd: 'add', a: 1, b: 1}, function (err, resp) {
//or
this.meta$.token = 'ABC1234';
this.act({ topic: 'math', cmd: 'add', a: 1, b: 5 });
});
If you want to set a context across all act
you can use the context$
property.
hemera.context$.a = 'foobar';
hemera.act({ topic: 'math', cmd: 'add', a: 1, b: 1 }, function (err, resp) {
this.act({ topic: 'math', cmd: 'add', a: 1, b: 5 }, function (err, resp) {
this.context$.a // 'foobar'
});
});
If you want to set a context only for this act
and all nested act
hemera.act({ topic: 'math', cmd: 'add', a: 1, b: 1, context$: 1 }, function (err, resp) {
this.act({ topic: 'math', cmd: 'add', a: 1, b: 5 }, function (err, resp) {
this.context$ // 1
});
});
Hemera includes a payload validator called parambulator
hemera.add({
topic: 'math',
cmd: 'add',
a: {
type$: 'number'
}
}, (resp, cb) => {
cb(null, {
result: resp.a + resp.b
});
});
Handling
hemera.act({ topic: 'math', cmd: 'add', a: '1' }, function (err, resp) {
err instanceOf PayloadValidationError //true
});
let myPlugin = function (options) {
let hemera = this;
hemera.add({
topic: 'math',
cmd: 'add'
}, (resp, cb) => {
cb(null, {
result: resp.a + resp.b
});
});
};
hemera.use({ plugin: myPlugin, attributes: { name: 'myPlugin' }, options: { } })
const hemera = new Hemera(nats, { logLevel: 'info' });
[2016-11-17T21:04:47.608Z] INFO (app/18196 on starptech): ACT
topic: "math"
cmd: "add"
a: 1
b: 2
[2016-11-17T21:04:47.613Z] INFO (app/18196 on starptech): ACT_RESP
topic: "math"
cmd: "add"
a: 1
b: 2
time$: 2
hemera.on('outbound', (msg) => {
console.log('Outbound', msg)
})
hemera.on('inbound', (msg) => {
console.log('Inbound', msg)
})
Format: JSON
{
"pattern": "<msg>",
"meta$": "<msg>",
"request$": "<msg>"
}
{
"result": "<msg>",
"error": "<serialized_error>",
"meta$": "<msg>",
"response$": "<msg>"
}
Think in small parts. A topic is like a service. You can define a service like auth
which is responsible for authenticate users.
This service has actions like:
hemera.add({ topic: 'auth', cmd: 'authenticate' })
hemera.add({ topic: 'auth', cmd: 'passwordReset' })
...
Now your service is scaled.
node service.js
node service.js
Now your service is fault-tolerant.
var servers = ['nats://nats.io:4222', 'nats://nats.io:5222', 'nats://nats.io:6222'];
var nc = nats.connect({'servers': servers});
new Hemera(nc);
https://www.youtube.com/watch?v=NfL0WO44pqc
http://nats.io/documentation/faq/
The simplicity and focus of NATS enables it to deliver superior performance and stability with a lightweight footprint. It has the potential of becoming the de-facto transport for microservice architectures and event driven systems in this new era.
Asim Aslam, Creator of Micro
"I discovered NATS for its performance, and stayed for its simplicity. It’s been a wonderfully reliable layer that connects our microservice architecture at Pressly. The source is easily readable and approachable, and the future developments keep me excited!
Peter Kieltyka - CTO, Pressly
Set the path to the gnatsd
before start testing.
npm run test
Easy and beauitiful tool to monitor you app. natsboard
Please read CONTRIBUTING.md for details on our code of conduct, and the process for submitting pull requests to us.
We use SemVer for versioning. For the versions available, see the tags on this repository.
See also the list of contributors who participated in this project.
This project is licensed under the MIT License - see the LICENSE.md file for details
Seneca - A microservices toolkit for Node.js.
FAQs
The core package of hemera
We found that nats-hemera demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Fluent Assertions is facing backlash after dropping the Apache license for a commercial model, leaving users blindsided and questioning contributor rights.
Research
Security News
Socket researchers uncover the risks of a malicious Python package targeting Discord developers.
Security News
The UK is proposing a bold ban on ransomware payments by public entities to disrupt cybercrime, protect critical services, and lead global cybersecurity efforts.