【发布时间】:2015-05-19 08:44:56
【问题描述】:
我目前正在开发一个 API 管理器来控制现有 API 的项目。
它包含“之前”和“之后”中间件的列表,用于执行安全检查和日志记录等操作。和一个“服务”中间件对现有 API 进行 http 请求。但问题是我想让中间件的执行顺序是动态的,这意味着我可以加载一些配置文件来更改每次请求进入时中间件的执行顺序。
这是我之前的代码:
'use strict';
// Loading the express library
var express = require('express');
var app = express();
var service = require('./routes/index');
// Testing configurable middleware
var confirguration = {
before1: {
priority: 100,
enable: true
},
before2: {
priority: 80,
enable: true
},
service: {
priority: 50,
enable: true
},
after1: {
priority: 30,
enable: true
},
after2: {
priority: 10,
enable: true
}
}
var before1 = require('./example_middleware/before1');
var before2 = require('./example_middleware/before2');
var after1 = require('./example_middleware/after1');
var after2 = require('./example_middleware/after2');
// Fake request to simulate the /service
var fakeRequest = require('./example_middleware/fake_request');
// Function to sort the order of the middleware to be executed
var sortConfig = function(confirguration){
var sortable = [];
for (var middleware in confirguration)
// To make middlewares configurable
if (confirguration[middleware]['enable'] == true){
sortable.push([middleware, confirguration[middleware]['priority']]);
}
sortable.sort(function(a, b) {return b[1] - a[1]});
return sortable;
}
// var sortedConfig = [];
var middlewareSet = new Array();
app.use('/test', function(request, response, next){
var middleware;
var sortedConfig = sortConfig(confirguration);
for (var i in sortedConfig){
switch(sortedConfig[i][0]){
case 'before1':
middleware = before1;
break;
case 'before2':
middleware = before2;
break;
case 'service':
middleware = fakeRequest;
break;
case 'after1':
middleware = after1;
break;
case 'after2':
middleware = after2;
break;
}
// console.log(sortedConfig[i][0]);
// Execute the middleware in expected order
middlewareSet.push(middleware);
}
// request.sortedConfig = sortedConfig;
console.log(middlewareSet);
console.log('middleware list sorted');
next();
});
app.use('/test', middlewareSet);
但我不断收到来自 app.use() 最后一行的相同错误消息:
app.use() 需要中间件函数
如果我使用它会起作用:
app.use('/test', [before1, before2, fakeRequest, after1, after2]);
但它不是动态的,我误解了什么? express.js 中一定有办法做到这一点。
提前致谢。
编辑: 我根据 Ryan 的回答修改了我的代码,代码如下:
var async = require('async');
app.use('/test', configurableMiddleWare);
function configurableMiddleWare(req, res, next) {
var operations = [];
var middleware;
var sortedConfig = sortConfig(confirguration);
// push each middleware you want to run
sortedConfig.forEach(function(fn) {
switch(fn[0]){
case 'before1':
middleware = before1;
break;
case 'before2':
middleware = before2;
break;
case 'service':
middleware = fakeRequest;
break;
case 'after1':
middleware = after1;
break;
case 'after2':
middleware = after2;
break;
}
operations.push(middleware); // could use fn.bind(null, req, res) to pass in vars
});
console.log('middleware list sorted');
// now actually invoke the middleware in series
async.series(operations, function(err) {
if(err) {
// one of the functions passed back an error so handle it here
return next(err);
}
// no errors so pass control back to express
next();
});
}
为了确保我的测试中间件没有犯任何错误,这里是其中之一的示例:
'use strict';
var express = require('express');
var router = express.Router();
router.route('/')
.all(function(request, response, next){
console.log('This is middleware BEFORE1');
next();
});
module.exports = router;
现在,当我运行我的应用程序时,我从 npm 收到以下错误:
TypeError: 无法调用未定义的方法 'indexOf'
在 Function.proto.handle (/Users/jialunliu/Documents/SOA_project/FAT-LADY/node_modules/express/lib/router/index.js:130:28) 在路由器(/Users/jialunliu/Documents/SOA_project/FAT-LADY/node_modules/express/lib/router/index.js:35:12) 在 /Users/jialunliu/Documents/SOA_project/FAT-LADY/node_modules/async/lib/async.js:610:21 在 /Users/jialunliu/Documents/SOA_project/FAT-LADY/node_modules/async/lib/async.js:249:17 在迭代(/Users/jialunliu/Documents/SOA_project/FAT-LADY/node_modules/async/lib/async.js:149:13) 在 async.eachSeries (/Users/jialunliu/Documents/SOA_project/FAT-LADY/node_modules/async/lib/async.js:165:9) 在_asyncMap (/Users/jialunliu/Documents/SOA_project/FAT-LADY/node_modules/async/lib/async.js:248:13) 在 Object.mapSeries (/Users/jialunliu/Documents/SOA_project/FAT-LADY/node_modules/async/lib/async.js:231:23) 在 Object.async.series (/Users/jialunliu/Documents/SOA_project/FAT-LADY/node_modules/async/lib/async.js:608:19) 在configurableMiddleWare (/Users/jialunliu/Documents/SOA_project/FAT-LADY/app.js:135:11)
来自线路
async.series(operations, function(err){})
我不断收到这种错误消息,说函数无法从这个函数数组“操作”中读取......
【问题讨论】:
标签: javascript node.js express