Skip to content

Instantly share code, notes, and snippets.

@umidjons
Created April 26, 2016 09:08
Show Gist options
  • Save umidjons/47f616867cf35592512e4c52a9259fc6 to your computer and use it in GitHub Desktop.
Save umidjons/47f616867cf35592512e4c52a9259fc6 to your computer and use it in GitHub Desktop.
Simple microservice with Seneca and Express

Simple microservice with Seneca and Express

Microservice implementation

Installing microservice dependencies

mkdir mathms
cd mathms
npm init
npm i seneca -S

Seneca 'Math' plugin

File mathms/MathPlugin.js:

module.exports = function MathPlugin(options) {
    this.add('role:math,cmd:sum', sum);
    this.add('role:math,cmd:product', product);

    // middleware for 'role:math,*' pins, that prepares values and calls actions themselves
    this.wrap('role:math', function (msg, respond) {
        msg.left = Number(msg.left).valueOf();
        msg.right = Number(msg.right).valueOf();

        // execute previously matched action
        this.prior(msg, respond);
    });

    function sum(msg, respond) {
        respond(null, {answer: msg.left + msg.right});
    }

    function product(msg, respond) {
        respond(null, {answer: msg.left * msg.right});
    }
};

Seneca 'Math' microservice

File mathms/MathMS.js:

require('seneca')()
    .use('MathPlugin') // equal to .use(require('./MathPlugin'))
    .listen({
        type: 'tcp', // communicate via TCP
        pin: 'role:math' // listen only this pin pattern
    });

Running the microservice

Run our mathms/MathMS.js with the following command:

node MathMS

Sample output looks like to this:

2016-04-26T08:21:53.579Z iqpuwz8vca8t/1461658913554/2348/- INFO hello   Seneca/2.0.1/iqpuwz8vca8t/1461658913554/2348/-
2016-04-26T08:21:54.924Z iqpuwz8vca8t/1461658913554/2348/- INFO listen  {type:tcp,pin:role:math}

Express application implementation

Installing application dependencies

mkdir myapp
cd myapp
npm init
npm i express body-parser seneca -S

Seneca 'MathAPI' plugin

File myapp/MathAPI.js:

module.exports = function MathAPI(options) {

    // valid operations list
    var valid_ops = {sum: 'sum', product: 'product'};

    this.add('role:api,path:calculate', function (msg, respond) {
        // talking to the microservice
        this.act('role:math', {
            cmd: valid_ops[msg.operation],
            left: msg.left,
            right: msg.right
        }, respond);
    });

    // plugin initialization
    this.add('init:MathAPI', function (msg, respond) {
        // http://localhost:3000/api/calculate/sum?left=2&right=3
        //                       ^      ^       ^   ^-------^
        //                  prefix action operation arguments
        this.act('role:web', {
            use: {
                prefix: '/api',
                pin: 'role:api,path:*',
                map: {
                    calculate: {GET: true, suffix: '/:operation'}
                }
            }
        }, respond);
    });
};

Express application

File myapp/server.js:

var seneca = require('seneca')()
    .use('MathAPI') // equal to .use(require('./MathAPI'))
    .client({type: 'tcp', pin: 'role:math'});

var app = require('express')()
    .use(require('body-parser').json())
    .use(seneca.export('web'))
    .listen(3000);

Running the express application

node server.js

Sample output looks like to this:

2016-04-26T08:24:40.571Z obe5f3hoxbu4/1461659080545/7820/- INFO hello   Seneca/2.0.1/obe5f3hoxbu4/1461659080545/7820/-
2016-04-26T08:24:40.944Z obe5f3hoxbu4/1461659080545/7820/- INFO client  {type:tcp,pin:role:math}

Testing express application

Send GET requests to the following URLs or open them in a web browser:

  • http://localhost:3000/api/calculate/sum?left=2&right=3 outputs {answer: 5}
  • http://localhost:3000/api/calculate/product?left=2&right=3 outputs {answer: 6}

Resources

@1fabiopereira
Copy link

I try it but my terminal show:

/home/fabio/Área de Trabalho/microservice/myapp/node_modules/express/lib/application.js:209
    throw new TypeError('app.use() requires middleware functions');
    ^

TypeError: app.use() requires middleware functions
    at EventEmitter.use (/home/fabio/Área de Trabalho/microservice/myapp/node_modules/express/lib/application.js:209:11)
    at Object.<anonymous> (/home/fabio/Área de Trabalho/microservice/myapp/server.js:7:6)
    at Module._compile (module.js:409:26)
    at Object.Module._extensions..js (module.js:416:10)
    at Module.load (module.js:343:32)
    at Function.Module._load (module.js:300:12)
    at Function.Module.runMain (module.js:441:10)
    at startup (node.js:139:18)
    at node.js:974:3

@makemek
Copy link

makemek commented Mar 26, 2017

Same error.
Found out that the docs are out of date.
Similarly in senecajs/seneca#585

Already been fixed and merged in
senecajs-attic/getting-started#12
senecajs/senecajs.org#281

Please see those PR

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment