express-rate-limit
is quite a popular package. So I don't think it is an anti-pattern.
Middleware can be chained.
For example, you want to impose both someRouteLimit
and apiLimit
on /some-route
app.get("/some-route",apiLimit,someRouteLimit,routeHandler)
The middleware is executed in order so you want to put the more restrictive one after the laxer one.
Express middleware hierarchy:
- Application-level middleware
- Router-level middleware
app.use("/", globalLimit)
is an application-level middleware so it will be executed first before all other middleware but before/after other application-level middleware depending on the order of which they are called.
You can also group routes using routers and apply the rate limit middleware on specific routers.
In your app.js
or index.js
:
// Depedencies
const express = require('express')
const rateLimit = require('express-rate-limit')
// Initialize the app
const app = express()
const globalLimit = rateLimit({
windowMs: 60 * 60 * 1000, // 1 HOUR
max: 500 // MAX 500 REQUESTS
});
const apiLimit = rateLimit({
windowMs: 60 * 60 * 1000, // 1 HOUR
max: 100 // MAX 100 REQUESTS
});
// Load Routes
const routeOne = require('./routes/routeOne');
const routeTwo = require('./routes/routeTwo');
// Use routes
app.use('/', routeOne,apiLimit); // Impose apiLimit on this router
app.use('/', routeTwo); // No router-level middleware is applied
app.listen(portNumber)
In the routeOne: (restricted by both globalLimit
and apiLimit
)
const express = require('express');
const router = express.Router();
const rateLimit = require('express-rate-limit')
const someRouteLimit = rateLimit({
windowMs: 60 * 60 * 1000, // 1 HOUR
max: 10 // MAX 10 REQUESTS
});
// Some Route (further restricted by someRouteLimit)
router.post('/some-route',someRouteLimit, routeHandler);
module.exports = router;
In RouteTwo: (Restricted by globalLimit
but not apiLimit
)
const express = require('express');
const router = express.Router();
const rateLimit = require('express-rate-limit')
const someRouteLimit2 = rateLimit({
windowMs: 60 * 60 * 1000, // 1 HOUR
max: 10 // MAX 10 REQUESTS
});
// Some Route (further restricted by someRouteLimit2)
router.post('/some-route2',someRouteLimit, routeHandler);
module.exports = router;
If you want to implement your middleware in a more customized manner, there are some more creative methods using regex and custom helper function in this post.