Simplistic µService library
The goal of mini-service is to give the minimal structure to implement a µService, that can be invoked locally or remotely.
Its principles are the following:
- very easy to add new service api endpoints
 - easy to use client interface, same usage both locally and remotely
 - hide deployment details and provide simple-yet-working solution
 - promises based (and thus, async/await compatible)
 
mini-service uses the latest ES6 features, so it requires node 6+
Here is a simple calculator service definition, that exposes functions to add and subtract numbers.
calc-service.js
module.exports = {
  name: 'calc-service',
  version: '1.0.0',
  init: () => {
    // each exposed APIs could also return a promise/be async
    add: (a, b) => a + b,
    subtract: (a, b) => a - b
  }
}If you want to use it locally in a different file: require the service definition, and create a [mini-client][mini-client-url] with it
caller-local.js
const {getClient} = require('mini-service')
const calcService = require('./calc-service')
const calc = getClient(calcService)Then, init it (it's an async operation) and invoke any exposed API you need:
caller-local.js
await calc.init()
const sum = await calc.add(10, 5)
console.log(`Result is: ${sum}`)Now let's imagine you need to deploy your calculator service in a standalone Http server, and invoke it from a remote server.
To turn your local service into a real server, expose your service definition with mini-service's startServer():
calc-service.js
const {startServer} = require('mini-service')
module.exports = {...} // same service definition as above
// starts Http server
startServer(module.exports)A server is now listening on port 3000.
And to use it from a remote caller, creates a mini-client giving the proper url:
caller-remote.js
const getClient = require('mini-client') // or: const {getClient} = require('mini-service')
const calc = getClient({
  remote: 'http://localhost:3000'
})Please note that you don't need to require the service definition anymore.
Usage is exactly the same as previously.
caller-remote.js
await calc.init() // no-op, can be skipped
const sum = await calc.add(10, 5)
console.log(`Result is: ${sum}`)This project was kindly sponsored by nearForm.
Copyright Damien Simonin Feugas and other contributors, licensed under MIT.
## Changelog & migration guide
All changes to this project are be documented here.
The format is based on Keep a Changelog and this project adheres to Semantic Versioning.
Version 4 is using async/await, which requires node@8+.
The only breaking change is on startServer():
- previously it threw synrchonous errors while validating configuration.
 - now all errors are thrown asynchronously
 
Groups are now used as sub-objects of mini-client.
Given a service exposing:
- api 
pingwithout group (or if group has same name as overall service) - group 
awith apisping&pong - group 
bwith apiping 
the final Mini-client will be:
client = {
  ping(),
  a: {
    ping(),
    pong()
  },
  b: {
    ping()
  }
}Local services, as remote services, must have name and version options defined
When loading services, the services property was renamed to groups, and serviceOpts is now groupOpts:
const {startServer} = require('mini-service')
startServer({
  groups: [ // was services previously
    require('../serviceA'),
    require('../serviceB'),
    require('../serviceC')
  ],
  groupOpts: { // was serviceOpts previously
    serviceA: {},
    serviceB: {},
    serviceC: {}
  }
})