Middleware-Engine
A lightweight engine that provides middleware functionality to classes that extend it.
Quick Start
You must extend the MiddlewareEngine
class to use its functionality.
const MiddlewareEngine = ; { super /* Config for Middleware-Engine goes here... */ ; } { return Promise ; } const instance = ; instance; // Executed 1st.instance; // Executed 4th. instance; // Executed 2nd.instance; // Executed 3rd. instance ;
For a fully-featured example take a look at the source code for the Ultimail module.
API Overview
const engine = new MiddlewareEngine(config);
You must extend the MiddlewareEngine
class and call the this.__executeMiddleware()
or this.__executeHandler()
methods to use its functionality.
Config Options
You can supply the following config to the constructor.
Config | Default Value | Description |
---|---|---|
chainMiddlewareResults | false |
Set to true to pass the result of the previous middleware execution to the next middleware function as the second to last parameter. |
throwOnMissingHandler | true |
Set to false to prevent an error being thrown if you call this.__executeHandler() on a handler ID that hasn't been configured. |
throwOnMissingDependency | true |
Set to false to prevent an error being thrown if you call this.__dep() for a dependency that hasn't been injected. |
engine.use(func1, func2, ...funcN);
Can be used externally by the consumer of your class. Add a number of middleware functions by providing one or more arguments. You can call .use()
as many times as you like or with as many arguments as you like. The middleware is always executed in the order you add them.
engine.configure(handlerId, func1, func2, ...funcN);
Can be used externally by the consumer of your class. Add named handler middleware that should be executed at a specific point by your class, either before or after the general middleware added with .use()
. You can only call this method once for each handlerId
, if you call it a second time the handler will be replaced.
engine.isConfigured(handlerId);
Can be used externally by the consumer of your class. Returns true if the given handler ID has been configured with the .configure()
method.
engine.requires()
Returns an array of required dependencies configured by your class (i.e. added to the this.requirements
array).
engine.inject(dependencyName, dependencyObject);
Can be used externally by the consumer of your class. Allows you to inject a dependency into your class which can be accessed inside your class by calling this.__dep()
(see below). You can inject as many dependencies as you like by calling this method multiple times.
engine.areDependenciesSatisfied()
Returns true if all the dependencies configured by your class have been injected.
engine.hasDependency(dependencyName)
Returns true if the given dependency has been injected.
this.__executeMiddleware(primaryValue, arg1, arg2, ...argN);
Only to be used internally by your class. Call this to execute all the middleware that has been added by the consumer via the .use()
method. Middleware is always executed in the order it was added.
You can pass as many parameters as you like to this method and they will all be passed to each middleware function. You can use the primaryValue
parameter to pass in an object/array that you want shared between each of the middleware functions (similar to how you can access the request
and response
objects in every Express.js middleware).
Default Middleware signature
function (primaryValue, arg1, arg2, ...argN, next, stop) { ... }
.
You must call the next(err, result)
callback at the end of every middleware or your application will hang. Alternatively, if you're waiting for all the middleware to complete and the promise to be resolved before continuing execution in your application you can use the stop()
method to immediately resolve the promise. You can also pass an error to stop(err)
.
Alternative Middleware Signature
function (primaryValue, ...argN, previousResult, next, stop) { ... }
The result of the previous middleware execution will be available as the second to last parameter previousResult
if the config option chainMiddlewareResults
is set in the constructor.
this.__executeHandler(handlerId, primaryValue, arg1, arg2, ...argN);
Only to be used internally by your class. Call this to execute only the middleware functions configured as part of the named handler with .configure()
. Middleware is always executed in the order it was added.
You can pass as many parameters as you like to this method and they will all be passed to each middleware function. You can use the primaryValue
parameter to pass in an object/array that you want shared between each of the middleware functions (similar to how you can access the request
and response
objects in every Express.js middleware).
By default, if the handler ID has not been configured an error will be thrown. You can silently swallow the error instead by setting the throwOnMissingHandler
config to false
in the constructor.
Default Middleware signature
function (primaryValue, arg1, arg2, ...argN, next, stop) { ... }
You must call the next(err, result)
callback at the end of every middleware or your application will hang. Alternatively, if you're waiting for all the middleware to complete and the promise to be resolved before continuing execution in your application you can use the stop()
method to immediately resolve the promise. You can also pass an error to stop(err)
.
Alternative Middleware Signature
function (primaryValue, ...argN, previousResult, next, stop) { ... }
.
The result of the previous middleware execution will be available as the second to last parameter previousResult
if the config option chainMiddlewareResults
is set to true
in the constructor.
this.__dep(dependencyName);
Only to be used internally by your class. Returns the given injected dependency.