I have a node app sitting like a firewall/dispatcher in front of other micro services and it uses a middleware chain like below:
...
app.use app_lookup
app.use timestamp_validator
app.use request_body
app.use checksum_validator
app.use rateLimiter
app.use whitelist
app.use proxy
...
However for a particular GET route I want to skip all of them except rateLimiter and proxy. Is their a way to set a filter like a Rails before_filter using :except/:only?
To exclude a route from running an Express middleware, we can create our own function that accepts a route path and middleware function and returns a middleware function that checks the route path before running the middleware function.
They are not middleware functions by definition. If such function is used on routing methods then they are only handler functions. We use such a handler function which is not a middleware when it is the only one callback function.
Middleware literally means anything you put in the middle of one layer of the software and another. Express middleware are functions that execute during the lifecycle of a request to the Express server. Each middleware has access to the HTTP request and response for each route (or path) it's attached to.
Exclude a route from middleware prevent middleware from running defined express routes Thu, 03 Jan 2019 I had to implement this on one of my routes in a project that I’m currently working on. I use jwt tokens to make sure only authorized users can access my api and recently I needed to have a route that required no auth.
We can stop middleware from running on certain routes or request methods by using the express-unless package. To use it, we just set the unless function exposed from the package and set it to the unless property of our middleware function. Then we can exclude routes by using various conditions by checking the URL and/or request method.
We can exclude calling the express.static middleware when we have the jpg , html , css or .js extensions as follows: In the code above, we check the extensions of the req.originalUrl property to see if they the request have the extensions listed in the array and skip the static middleware if they’re there.
If we want to skip a middleware we can pass parameters to the middleware function and decide based on that parameter which middleware to call and which middleware to not call. express.js: To handle routing.
Even though there is no build-in middleware filter system in expressjs, you can achieve this in at least two ways.
First method is to mount all middlewares that you want to skip to a regular expression path than includes a negative lookup:
// Skip all middleware except rateLimiter and proxy when route is /example_route
app.use(/\/((?!example_route).)*/, app_lookup);
app.use(/\/((?!example_route).)*/, timestamp_validator);
app.use(/\/((?!example_route).)*/, request_body);
app.use(/\/((?!example_route).)*/, checksum_validator);
app.use(rateLimiter);
app.use(/\/((?!example_route).)*/, whitelist);
app.use(proxy);
Second method, probably more readable and cleaner one, is to wrap your middleware with a small helper function:
var unless = function(path, middleware) {
return function(req, res, next) {
if (path === req.path) {
return next();
} else {
return middleware(req, res, next);
}
};
};
app.use(unless('/example_route', app_lookup));
app.use(unless('/example_route', timestamp_validator));
app.use(unless('/example_route', request_body));
app.use(unless('/example_route', checksum_validator));
app.use(rateLimiter);
app.use(unless('/example_route', whitelist));
app.use(proxy);
If you need more powerfull route matching than simple path === req.path
you can use path-to-regexp module that is used internally by Express.
UPDATE :- In express 4.17
req.path
returns only '/', so use req.baseUrl
:
var unless = function(path, middleware) {
return function(req, res, next) {
if (path === req.baseUrl) {
return next();
} else {
return middleware(req, res, next);
}
};
};
Built upon the answer from @lukaszfiszer as I wanted more than one route excluded. You can add as many as you want here.
var unless = function(middleware, ...paths) {
return function(req, res, next) {
const pathCheck = paths.some(path => path === req.path);
pathCheck ? next() : middleware(req, res, next);
};
};
app.use(unless(redirectPage, "/user/login", "/user/register"));
Can't add as comment sorry.
You can also skip route like this by putting a condition on req.originalUrl:
app.use(function (req, res, next) {
if (req.originalUrl === '/api/login') {
return next();
} else {
//DO SOMETHING
}
I use this regular expression with success : /^\/(?!path1|pathn).*$/
.
There's a lot of good answers here. I needed a slightly different answer though.
I wanted to be able to exclude middleware from all HTTP PUT requests. So I created a more general version of the unless
function that allows a predicate to be passed in:
function unless(pred, middleware) {
return (req, res, next) => {
if (pred(req)) {
next(); // Skip this middleware.
}
else {
middleware(req, res, next); // Allow this middleware.
}
}
}
Example usage:
app.use(unless(req => req.method === "PUT", bodyParser.json()));
You can define some routes like below.
app.use(/\/((?!route1|route2).)*/, (req, res, next) => {
//A personal middleware
//code
next();//Will call the app.get(), app.post() or other
});
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