- Rate Limit Map Initialization
const rateLimitMap = new Map();
Here, we initialize a new JavaScript Map called rateLimitMap
. This map will store information about the number of requests made by each IP address and when the last reset occurred.
- Rate Limit Middleware Function
export default function rateLimitMiddleware(handler) {
return (req, res) => {
// Code logic goes here
};
}
This function is the middleware responsible for implementing rate limiting. It takes a handler
function as an argument, which represents the logic of the API route that we want to protect with rate limiting.
- IP Address Extraction
const ip = req.headers["x-forwarded-for"] || req.connection.remoteAddress;
This line extracts the IP address of the client making the request. It first checks if there's an "x-forwarded-for" header, which is commonly used for proxies. If not, it falls back to req.connection.remoteAddress
.
- Rate Limit Configuration
const limit = 5; // Limiting requests to 5 per minute per IP
const windowMs = 60 * 1000; // 1 minute
Here, we set our rate limit configuration. We're limiting requests to 5 per minute per IP address. windowMs
defines the time window for the rate limit (1 minute in this case).
- IP Data Initialization
if (!rateLimitMap.has(ip)) {
rateLimitMap.set(ip, {
count: 0,
lastReset: Date.now(),
});
}
This block initializes data for the IP address if it's not already present in the rateLimitMap
. It sets the request count to 0 and records the current time as the last reset time.
- Time Window Reset
const ipData = rateLimitMap.get(ip);
if (Date.now() - ipData.lastReset > windowMs) {
ipData.count = 0;
ipData.lastReset = Date.now();
}
Here, we check if the time window for the rate limit has passed since the last reset. If it has, we reset the request count to 0 and update the last reset time to the current time.
- Rate Limit Check
if (ipData.count >= limit) {
return res.status(429).send("Too Many Requests");
}
This block checks if the request count for the IP address has exceeded the limit. If it has, we respond with a "Too Many Requests" status code (429).
- Request Count Increment
ipData.count += 1;
Finally, we increment the request count for the IP address by 1, indicating that a new request has been received within the time window.
- Handler Invocation
return handler(req, res);
Once all checks are passed, we invoke the original handler function to proceed with the logic of the API route.
To test the rate limiting middleware, follow these steps:
- Run your Next.js project in development mode:
npm run dev
- Visit the following URLs in your browser to observe the rate limiting behavior:
- http://localhost:3000/api/limited (for limited requests)
- http://localhost:3000/api/unlimited (for unlimited requests)
Observe how the rate limiting middleware behaves differently based on the configured limits.
This middleware function acts as a gatekeeper for our API routes, ensuring that no single IP address exceeds the defined request limit within the specified time window. It's a crucial tool for maintaining the stability and performance of our server, especially under heavy traffic or potential attacks.
This markdown includes the explanation of the rate limiting middleware as well as the steps to test it in your Next.js project.