I have a few middlewares that I want to combine into one middleware. How do I do that?
For example...
// I want to shorten this...
app.use(connect.urlencoded())
app.use(connect.json())
// ...into this:
app.use(combineMiddleware([connect.urlencoded, connect.json]))
// ...without doing this:
app.use(connect.urlencoded()).use(connect.json())
I want it to work dynamically -- I don't want to depend on which middleware I use.
I feel like there's an elegant solution other than a confusing for
loop.
use() to add a middleware function to our Express application. Express will first execute function1 and then function2 . Middleware functions in Express are of the following types: Application-level middleware which runs for all routes in an app object.
Middleware sits between an operating system and the applications that run on it. It is effectively software that provides a method of communication and data management between applications that would otherwise not have any way to exchange data -- such as with software tools and databases.
Next. js' middleware allows you to create functions that execute after a user's request is made and before the request is completed — in the middle of the two processes. This enables you to process a user's request and then modify the response by rewriting, redirecting, modifying headers, or even streaming HTML.
Express accepts arrays for app.use
if you have a path:
var middleware = [connect.urlencoded(), connect.json()];
app.use('/', middleware)
However, if you want a generic combineMiddleware
function, you can build a helper easily without any additional libraries. This basically takes advantage of the fact that next
is simply a function which takes an optional error:
/**
* Combine multiple middleware together.
*
* @param {Function[]} mids functions of form:
* function(req, res, next) { ... }
* @return {Function} single combined middleware
*/
function combineMiddleware(mids) {
return mids.reduce(function(a, b) {
return function(req, res, next) {
a(req, res, function(err) {
if (err) {
return next(err);
}
b(req, res, next);
});
};
});
}
If you like fancy stuff, here is one of possible solutions:
var connect = require('connect')
var app = connect()
function compose(middleware) {
return function (req, res, next) {
connect.apply(null, middleware.concat(next.bind(null, null))).call(null, req, res)
}
}
function a (req, res, next) {
console.log('a')
next()
}
function b (req, res, next) {
console.log('b')
next()
}
app.use(compose([a,b]))
app.use(function (req, res) {
res.end('Hello!')
})
app.listen(3000)
Here is what it does: compose
function takes array of middleware and return composed middleware. connect
itself is basically a middleware composer, so you can create another connect app with middlewares you want: connect.apply(null, middleware)
. Connect app is itself a middleware, the only problem is that it doesn't have a next()
call in the end, so subsequent middleware will be unreachable. To solve that, we need another last
middleware, which will call next
: connect.apply(null, middleware.concat(last))
. As last only calls next
we can use next.bind(null, null)
instead. Finally, we call resulting function with req
and res
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With