Promisify Seneca microservice

Convert an asynchronous operation to promise-returning one.

I am playing with microservices using Seneca library. Here is a microservice that adds two numbers, plus a client using it. This example comes directly from the Getting started page

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
var seneca = require('seneca')();
// add registers a new service
seneca.add({
feature: 'math',
service: 'sum'
}, function (msg, respond) {
respond(null, { sum: msg.a + msg. b });
});
// seneca.act asks any microservice that implements
// { feature: 'math', serice: 'sum' }
// to execute and return results
seneca.act({
feature: 'math',
service: 'sum',
a: 2,
b: 3
}, function (err, data) {
if (err) { throw err; }
console.log('2 + 3 = %d', data.sum);
});

I love the simplicity, but hate the callbacks. So I promisify the seneca.add using Bluebird library. Typically, one can convert all methods attached to an object using Promise.promisifyAll. In this case, notice that some seneca methods are not asynchronous. For example, seneca.add has Node-style looking callback, but it is just an event listener, not a response callback.

So I converted the seneca.act method only

1
2
3
4
5
6
7
8
9
10
11
var seneca = require('seneca')();
var Promise = require('bluebird');
seneca.actAsync = Promise.promisify(seneca.act, seneca);
seneca.actAsync({
feature: 'math',
service: 'sum',
a: 2,
b: 3
}).then(function (data) {
console.log('2 + 3 = %d', data.sum);
});

Notice that we are calling the actAsync function using <object>.<method> notation. Thus we do NOT need to attach the promisifed method to the seneca object.

1
2
3
seneca.actAsync = Promise.promisify(seneca.act);
// actAsync context = seneca
seneca.actAsync({ ... });

We saved a couple of characters and a whole variable.