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: {} } })