Implement app.middlewareFromConfig
Implement a function registering a middleware using a factory function and a JSON config. Example: app.middlewareFromConfig(compression, { enabled: true, phase: 'initial', config: { threshold: 128 } });
This commit is contained in:
parent
6aef836372
commit
5578d59631
|
@ -1,3 +1,4 @@
|
||||||
|
var assert = require('assert');
|
||||||
var express = require('express');
|
var express = require('express');
|
||||||
var merge = require('util')._extend;
|
var merge = require('util')._extend;
|
||||||
var PhaseList = require('loopback-phase').PhaseList;
|
var PhaseList = require('loopback-phase').PhaseList;
|
||||||
|
@ -12,6 +13,47 @@ module.exports = function loopbackExpress() {
|
||||||
return app;
|
return app;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register a middleware using a factory function and a JSON config.
|
||||||
|
*
|
||||||
|
* **Example**
|
||||||
|
*
|
||||||
|
* ```js
|
||||||
|
* app.middlewareFromConfig(compression, {
|
||||||
|
* enabled: true,
|
||||||
|
* phase: 'initial',
|
||||||
|
* config: {
|
||||||
|
* threshold: 128
|
||||||
|
* }
|
||||||
|
* });
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* @param {function} factory The factory function creating a middleware handler.
|
||||||
|
* Typically a result of `require()` call, e.g. `require('compression')`.
|
||||||
|
* @param {Array|*} config The configuration. Either an array of arguments
|
||||||
|
* to pass to the factory function, or the value of the first argument
|
||||||
|
* when the factory expects a single argument only.
|
||||||
|
*/
|
||||||
|
proto.middlewareFromConfig = function(factory, config) {
|
||||||
|
assert(typeof factory === 'function', '"factory" must be a function');
|
||||||
|
assert(typeof config === 'object', '"config" must be an object');
|
||||||
|
assert(typeof config.phase === 'string' && config.phase,
|
||||||
|
'"config.phase" must be a non-empty string');
|
||||||
|
|
||||||
|
if (config.enabled === false)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var args = config.config;
|
||||||
|
if (args === undefined) {
|
||||||
|
args = [];
|
||||||
|
} else if (!Array.isArray(args)) {
|
||||||
|
args = [args];
|
||||||
|
}
|
||||||
|
|
||||||
|
var handler = factory.apply(null, args);
|
||||||
|
this.middleware(config.phase, handler);
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Register a middleware handler to be executed in a given phase.
|
* Register a middleware handler to be executed in a given phase.
|
||||||
* @param {string} name The phase name, e.g. "init" or "routes".
|
* @param {string} name The phase name, e.g. "init" or "routes".
|
||||||
|
@ -23,6 +65,9 @@ module.exports = function loopbackExpress() {
|
||||||
proto.middleware = function(name, handler) {
|
proto.middleware = function(name, handler) {
|
||||||
this.lazyrouter();
|
this.lazyrouter();
|
||||||
|
|
||||||
|
assert(typeof name === 'string' && name, '"name" must be a non-empty string');
|
||||||
|
assert(typeof handler === 'function', '"handler" must be a function');
|
||||||
|
|
||||||
var fullName = name;
|
var fullName = name;
|
||||||
var handlerName = handler.name || '(anonymous)';
|
var handlerName = handler.name || '(anonymous)';
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
var path = require('path');
|
var path = require('path');
|
||||||
|
|
||||||
var http = require('http');
|
var http = require('http');
|
||||||
var loopback = require('../');
|
var loopback = require('../');
|
||||||
var PersistedModel = loopback.PersistedModel;
|
var PersistedModel = loopback.PersistedModel;
|
||||||
|
@ -27,7 +28,7 @@ describe('app', function() {
|
||||||
});
|
});
|
||||||
app.use(namedHandler('main'));
|
app.use(namedHandler('main'));
|
||||||
|
|
||||||
executeHandlers(function(err) {
|
executeMiddlewareHandlers(app, function(err) {
|
||||||
if (err) return done(err);
|
if (err) return done(err);
|
||||||
expect(steps).to.eql([
|
expect(steps).to.eql([
|
||||||
'initial', 'session', 'auth', 'parse',
|
'initial', 'session', 'auth', 'parse',
|
||||||
|
@ -42,7 +43,7 @@ describe('app', function() {
|
||||||
app.middleware('routes:after', namedHandler('routes:after'));
|
app.middleware('routes:after', namedHandler('routes:after'));
|
||||||
app.use(namedHandler('main'));
|
app.use(namedHandler('main'));
|
||||||
|
|
||||||
executeHandlers(function(err) {
|
executeMiddlewareHandlers(app, function(err) {
|
||||||
if (err) return done(err);
|
if (err) return done(err);
|
||||||
expect(steps).to.eql(['routes:before', 'main', 'routes:after']);
|
expect(steps).to.eql(['routes:before', 'main', 'routes:after']);
|
||||||
done();
|
done();
|
||||||
|
@ -64,7 +65,7 @@ describe('app', function() {
|
||||||
next();
|
next();
|
||||||
});
|
});
|
||||||
|
|
||||||
executeHandlers(function(err) {
|
executeMiddlewareHandlers(app, function(err) {
|
||||||
if (err) return done(err);
|
if (err) return done(err);
|
||||||
expect(steps).to.eql(['initial', 'error']);
|
expect(steps).to.eql(['initial', 'error']);
|
||||||
done();
|
done();
|
||||||
|
@ -78,7 +79,7 @@ describe('app', function() {
|
||||||
next(expectedError);
|
next(expectedError);
|
||||||
});
|
});
|
||||||
|
|
||||||
executeHandlers(function(err) {
|
executeMiddlewareHandlers(app, function(err) {
|
||||||
expect(err).to.equal(expectedError);
|
expect(err).to.equal(expectedError);
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
|
@ -90,18 +91,59 @@ describe('app', function() {
|
||||||
next();
|
next();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function executeHandlers(callback) {
|
|
||||||
var server = http.createServer(function(req, res) {
|
|
||||||
app.handle(req, res, callback);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
request(server)
|
describe.onServer('.middlewareFromConfig', function() {
|
||||||
.get('/test/url')
|
it('provides API for loading middleware from JSON config', function(done) {
|
||||||
.end(function(err) {
|
var steps = [];
|
||||||
if (err) return callback(err);
|
var expectedConfig = { key: 'value' };
|
||||||
|
|
||||||
|
var handlerFactory = function() {
|
||||||
|
var args = Array.prototype.slice.apply(arguments);
|
||||||
|
return function(req, res, next) {
|
||||||
|
steps.push(args);
|
||||||
|
next();
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
// Config as an object (single arg)
|
||||||
|
app.middlewareFromConfig(handlerFactory, {
|
||||||
|
enabled: true,
|
||||||
|
phase: 'session',
|
||||||
|
config: expectedConfig
|
||||||
|
});
|
||||||
|
|
||||||
|
// Config as a value (single arg)
|
||||||
|
app.middlewareFromConfig(handlerFactory, {
|
||||||
|
enabled: true,
|
||||||
|
phase: 'session:before',
|
||||||
|
config: 'before'
|
||||||
|
});
|
||||||
|
|
||||||
|
// Config as a list of args
|
||||||
|
app.middlewareFromConfig(handlerFactory, {
|
||||||
|
enabled: true,
|
||||||
|
phase: 'session:after',
|
||||||
|
config: ['after', 2]
|
||||||
|
});
|
||||||
|
|
||||||
|
// Disabled by configuration
|
||||||
|
app.middlewareFromConfig(handlerFactory, {
|
||||||
|
enabled: false,
|
||||||
|
phase: 'initial',
|
||||||
|
config: null
|
||||||
|
});
|
||||||
|
|
||||||
|
executeMiddlewareHandlers(app, function(err) {
|
||||||
|
if (err) return done(err);
|
||||||
|
expect(steps).to.eql([
|
||||||
|
['before'],
|
||||||
|
[expectedConfig],
|
||||||
|
['after', 2]
|
||||||
|
]);
|
||||||
|
done();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('app.model(Model)', function() {
|
describe('app.model(Model)', function() {
|
||||||
|
@ -470,3 +512,15 @@ describe('app', function() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
function executeMiddlewareHandlers(app, callback) {
|
||||||
|
var server = http.createServer(function(req, res) {
|
||||||
|
app.handle(req, res, callback);
|
||||||
|
});
|
||||||
|
|
||||||
|
request(server)
|
||||||
|
.get('/test/url')
|
||||||
|
.end(function(err) {
|
||||||
|
if (err) return callback(err);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue