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:
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.
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():
Groups are now used as sub-objects of mini-client.
Given a service exposing:
ping without group (or if group has same name as overall service)a with apis ping & pongb with api pingthe 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: {}
}
})