middleware-chainer
npm install middleware-chainerrequire('middleware-chainer')yaml
---------------------------------------------
$BASEDIR/api/swagger/swagger.yaml
---------------------------------------------
paths:
/auth:
x-swagger-router-controller: auth
post:
operationId: login
description: User Authentication/Authorization (Generate Token)
# ...
delete:
operationId: logout
description: Invalidate User Token/s
# ...
`
Here's the controller:
`javascript
/**
* $BASEDIR/api/controllers/auth.js
*/
const chain = require('middleware-chainer');
const loginHitCounter = require('./auth/login-hit-counter');
const loginErrorHandler = require('./auth/login-error-handler');
const login = require('./auth/login');
const logout = require('./auth/logout');
module.exports = {
login: chain({ middlewares: [loginHitCounter, login, loginErrorHandler] }),
logout: logout
};
`
In the example above, login has a "special 'pre' step (middleware)" prior to actual login, plus a special error handler.
Here's the would-be structure of the sample modularized swagger-generated project above:
`
/swagger-project
|-- /controllers
| |-- /auth
| | |-- login.js
| | |-- login.spec.js
| | |-- login-error-handler.js
| | |-- login-error-handler.spec.js
| | |-- login-hit-counter.js
| | |-- login-hit-counter.spec.js
| | |-- logout.js
| | |-- logout.spec.js
| |-- auth.js
| |-- auth.spec.js
|-- /swagger
| |-- swagger.yaml
`
Note: *.spec.js being unit tests.
$3
chain, pertaining to the variable where require('middleware-chainer') was assigned in the example above.
The chain function takes a single object literal {} as argument. Keys are as follows:
| Key | Type/Format | Description | Default | Example |
| --- | ----------- | ----------- | ------- | ------- |
| name | string | middleware name; shows in "debug" | 'mw-chain' | 'lol' |
| loggers | object literal (ie: {}) | see next two entries (loggers.*) | - | - |
| loggers.debug | function | receives "message" string as argument | () => undefined | console.log |
| loggers.error | function | receives "message" string as argument | console.error | console.log |
| middlewares | array of functions | array of middlewares (req, res[, next]) or (err, req, res, next) | - | - |
Sample "full" configuration:
`javascript
const debug = require('debug'); // https://www.npmjs.com/package/debug
const chain = require('middleware-chainer');
const chainedMiddleware = chain({
name: 'lol',
loggers: {
debug: debug,
error: debug
},
middlewares: [...]
});
`
Sample output from one of the unit tests with configured loggers.debug w/ console.log:
!loggers.png
Hint: Given the loggers.error has a default (console.error); you may opt to "mute" it by setting the value to: () => undefined.
Simple Usage :
require('middleware-chainer/simple')
`javascript
/**
* $BASEDIR/api/controllers/auth.js
*/
const chain = require('middleware-chainer/simple');
const loginHitCounter = require('./auth/login-hit-counter');
const loginErrorHandler = require('./auth/login-error-handler');
const login = require('./auth/login');
const logout = require('./auth/logout');
module.exports = {
login: chain(loginHitCounter, login, loginErrorHandler),
logout: logout
};
`
No fuss. Simple... Just middlewares.
Factory Usage :
require('middleware-chainer/factory')
`javascript
/**
* $BASEDIR/api/controllers/auth.js
*/
const ChainFactory = require('middleware-chainer/factory');
const loginHitCounter = require('./auth/login-hit-counter');
const loginErrorHandler = require('./auth/login-error-handler');
const loginChain = new ChainFactory({ // or ChainFactory({})
name: 'login-chain',
loggers: { debug: console.log },
before: [loginHitCounter],
after: [loginErrorHandler]
});
const login = require('./auth/login');
const refresh = require('./auth/refresh-token');
const logout = require('./auth/logout');
module.exports = {
login: loginChain(login), // chain(loginHitCounter, login, loginErrorHandler)
refresh: loginChain(refresh), // chain(loginHitCounter, refresh, loginErrorHandler)
logout: logout
};
`
Constructor arguments are very much the same as the "basic", apart from one omission and two additions:
| Key | Type/Format | Description | Default | Example |
| --- | ----------- | ----------- | ------- | ------- |
| ~~middlewares~~ | ~~array of functions~~ | ~~array of middlewares (req, res[, next]) or (err, req, res, next)~~ | - | - |
| before | array of functions | middlewares to be put at the beggining of the "chain" | - | - |
| after | array of functions | middlewares to be put at the end of the "chain" | - | - |
Principles/Inspiration
As described in this Wikipedia page, UNIT TESTING is described: "Intuitively, one can view a unit as the smallest testable part of an application". Therefore, being able to break-apart your application into smallest possible (sensible) modules is BEST!
If you employ/enforce the ideals of "single responsibility" per-class/file/module; middleware-chainer is an easy go-to.
100% Code Coverage
See for yourself!
1. Clone:
`bash
git clone https://github.com/jpbaking/middleware-chainer.git
`
1. ...of course go into folder:
`bash
cd middleware-chainer
`
1. Download/install dependencies:
`bash
npm install
`
1. Test!!!
`bash
npm test
``