1.0.5 • Published 4 years ago

emq-service v1.0.5

Weekly downloads
-
License
MIT
Repository
-
Last release
4 years ago

emq-service

EMQService

Microservice framework based on native Node.js HTTP module and AMQP protocol with express middleware & built-in prometheus. 🔬 🐇

Install

$ npm i emq-service

Tests

$ RABBIT_URL=amqp://localhost node tests/apps/users.js &
$ RABBIT_URL=amqp://localhost node tests/apps/balances.js &
$ RABBIT_URL=amqp://localhost PORT=3000 node tests/apps/gateway.js &
$ PORT=3000 npm test

Examples

There are some simple examples.

API

Gateway

.constructor(options)

This method creates gateway.

const Gateway = require('emq-service/gateway');

const gateway = new Gateway({
  microservices: ['users', 'orders'],
  rabbit: {
    url: 'amqp://localhost:5672',
  },
  requests: {
    timeout: 5000,
  },
});

.action(name, handler)

This method creates RPC action.

const Gateway = require('emq-service/gateway');
const { Users } = require('./db');

const gateway = new Gateway({ ... });

gateway.action('increase_balance', async (meta, res) => {
  if (!meta.amount || Number.isNaN(+meta.amount)) {
    res.status(400);
    res.json({ error: 'Bad data' });
    
    return;
  }
  
  await Users.updateOne({
    userId: meta.userId,
  }, {
    $inc: {
      balance: meta.amount,
    },
  });

  res.json({ ok: true });
});

gateway.listen(3000);
const EMQS = require('emq-service');

const app = new EMQS({ ... });

app.post('/deposit', (req, res) => {
  // send rpc action to the gateway
  res.json({
    server: {
      action: 'increase_balance',
      meta: {
        userId: 1,
        amount: 500,
      },
    },
  });
});

app.start();

.on(name, handler)

This method creates application event (read more).

const EMQS = require('emq-service');

const app = new EMQS({ ... });

// register event
app.on('error', (err, req, res) => {
  console.error(err); // 'Random error!'
});

app.use(async (req, res, next) => {
  try {
    await next();
  } catch (err) {
    res.status(err.status || 500);
    res.json({ error: err.message || 'Server error' });

    // emit event
    app.emit('error', err, req, res);
  }
});

app.post('/throw', (req, res) => {
  throw 'Random error!';
});

app.start();

.emit(name, ...args)

This method emits application event.

.enablePrometheus(endpoint, credentials)

This method enables prometheus monitoring.

const Gateway = require('emq-service/gateway');

const gateway = new Gateway({ ... });

// start prometheus with default /metrics endpoint & without credentials
gateway.enablePrometheus();

// start prometheus with /users/metrics endpoint & without credentials
gateway.enablePrometheus('/users/metrics');

// start prometheus with /users/metrics endpoint & credentials
gateway.enablePrometheus('/users/metrics', {
  user: 'admin',
  password: 'admin',
});

// start prometheus with default /metrics endpoint & credentials
gateway.enablePrometheus({
  user: 'admin',
  password: 'admin',
});

gateway.listen(3000);

.use(...middlewares)

This method adds middlewares.

.all(path, ...middlewares)

This method creates endpoint for all HTTP-methods.

.options(path, ...middlewares),

.get(path, ...middlewares),

.post(path, ...middlewares),

.put(path, ...middlewares),

.patch(path, ...middlewares),

.delete(path, ...middlewares)

This method creates endpoint with needed method.

.middleware()

This method returns middleware for express.

const express = require('express');
const bodyParser = require('body-parser');
const Gateway = require('emq-service/gateway');
const users = require('./routers/users');

const app = express();
const gateway = new Gateway({ ... });

app.use(bodyParser.json());

// apply middleware
app.use(gateway.middleware());

// monolith router
app.use('/users', users);

// delegate requests to the microservice
app.use('/orders', (req, res) => res.delegate('orders'));

.listen(port)

This method creates HTTP-server and starts listen needed port.

EMQS

.constructor(options)

This method creates microservice.

const EMQS = require('emq-service');

const app = new EMQS({
  microservice: 'users',
  rabbit: {
    url: 'amqp://localhost:5672',
  },
});

.action(name, handler)

This method creates RPC action.

const EMQS = require('emq-service');
const { Users } = require('./db');

const app = new EMQS({ ... });

app.action('new_deposit', async (meta, res) => {
  await Users.updateOne({
    userId: meta.userId,
  }, {
    $inc: {
      level: 1,
    },
  });


  res.json({ ok: true });
});

app.start();

.enablePrometheus(endpoint, credentials)

This method enables prometheus monitoring.

const EMQS = require('emq-service');

const app = new EMQS({ ... });

// start prometheus with default /metrics endpoint & without credentials
app.enablePrometheus();

// start prometheus with /users/metrics endpoint & without credentials
app.enablePrometheus('/users/metrics');

// start prometheus with /users/metrics endpoint & credentials
app.enablePrometheus('/users/metrics', {
  user: 'admin',
  password: 'admin',
});

// start prometheus with default /metrics endpoint & credentials
app.enablePrometheus({
  user: 'admin',
  password: 'admin',
});

app.start();

.use(...middlewares)

This method adds middlewares.

.all(path, ...middlewares)

This method creates endpoint for all HTTP-methods.

.options(path, ...middlewares),

.get(path, ...middlewares),

.post(path, ...middlewares),

.put(path, ...middlewares),

.patch(path, ...middlewares),

.delete(path, ...middlewares)

This method creates endpoint with needed method.

.ask(name, query)

This method asks other microservice.

const EMQS = require('emq-service');

const app = new EMQS({
  ...,
  microservices: ['balances'],
});

app.get('/users/me/info', async (req, res) => {
  // ask microservice endpoint
  const { response } = await app.ask('balances', {
    path: '/balances/me',
    method: 'get',
    params: {
      userId: req.params.id,
    },
  });
  
  // ask microservice action
  const { response } = await app.ask('balances', {
    server: {
      action: 'new_deposit',
      meta: {
        amount: 250,
      },
    },
  });
  
  res.json({
    id: req.params.id,
    name: `${req.session.first_name} ${req.session.last_name}`,
    balance: response.amount,
  });
});

app.start();

.listen(port)

This method creates HTTP-server and starts listen needed port. The usual use case for this method is run tests.

.start()

This method starts microservice.