Implementing Rate Limiting in Next.js App Router with In-Memory Counters 🔒⏱️
Demo :- https://ratex-nu.vercel.app/api
Codes :- https://github.com/SH20RAJ/rateLimitjs
Introduction:
Rate limiting is like a friendly bouncer at a party 🕺, making sure everyone gets a fair share of the fun without overwhelming the venue. 🏘️ It's crucial for protecting your web applications from excessive load and potential abuse, preventing Denial of Service (DoS) attacks, and ensuring the overall stability and performance of your system. 🛡️ With the introduction of the new app router in Next.js 13, implementing rate limiting may seem a bit different from the traditional approaches used in the pages router. But fear not, my friends! 💪 In this article, we'll explore how to set up rate limiting for your Next.js app router API routes using in-memory counters. 📈
Setting Up Rate Limiting with In-Memory Counters:
First things first, let's create a utility function that will handle the rate limiting logic. Create a new file called rateLimit.js
in your project's utils
folder (or any other location you prefer): 📂
let requestCounter = {};
let resetTimer;
const time = 5 * 1000; // 5 seconds
const requestLimit = 4; // 4 requests per 5 seconds
// Function to reset request counts
const resetCounters = () => {
requestCounter = {};
clearTimeout(resetTimer);
resetTimer = setTimeout(resetCounters, time);
};
resetCounters(); // Start the timer
export default async function rateLimit(req, res) {
const ip = (req.headers.get('x-forwarded-for') ?? '127.0.0.1').split(',')[0];
const clientIp = ({ ip }).ip;
requestCounter[clientIp] = requestCounter[clientIp] || 0;
if (requestCounter[clientIp] >= requestLimit) {
return true; // Rate limit exceeded 🚫
} else {
console.log('Request count for IP:', clientIp, '=', ++requestCounter[clientIp]);
return null; // Proceed with the request ✅
}
}
In this code:
- We initialize an empty object
requestCounter
to store the request counts for each client IP address. 📋 - We define the
time
variable as5 * 1000
milliseconds (5 seconds) and therequestLimit
variable as4
, allowing a maximum of 4 requests per 5 seconds. ⏱️ - The
resetCounters
function resets therequestCounter
object and sets a timeout to call itself after the specifiedtime
(5 seconds in this case). 🔄 - The
rateLimit
function is an async function that takes thereq
andres
objects as parameters. 🔍 - Inside the
rateLimit
function, we first retrieve the client's IP address from thex-forwarded-for
header or use127.0.0.1
as a fallback. We then extract the first IP address from the comma-separated list (in case there are multiple IP addresses in the header). 🌐 - We initialize the request count for the client IP address to 0 if it doesn't exist in the
requestCounter
object. 🆕 - If the request count for the client IP address is greater than or equal to the
requestLimit
(4 in this case), the function returnstrue
, indicating that the rate limit has been exceeded. 🚫 - If the request count is below the limit, it increments the request count for the client IP address, logs the updated count, and returns
null
, indicating that the request should proceed. ✅
Applying the Rate Limiting Middleware:
Now that we have the rate limiting middleware set up, we can apply it to our Next.js app router API routes. Open the route.js
file for your API route and import the rateLimit
function: 📝
import rateLimit from './rateLimit';
export const GET = async (req, res) => {
if (await rateLimit(req, res)) {
return new Response(JSON.stringify({ error: 'Rate limit exceeded. Please try again later.' }), {
status: 429,
headers: {
'Content-Type': 'application/json',
},
});
}
return new Response(JSON.stringify({ message: 'Hi' }), {
status: 200,
headers: {
'Content-Type': 'application/json',
},
});
};
- This file imports the
rateLimit
function from therateLimit.js
file. 📥 - Inside the
GET
route handler function, it calls therateLimit
function with thereq
andres
objects and awaits the result. ⏳ - If the
rateLimit
function returnstrue
(meaning the rate limit was exceeded), it returns a429 Too Many Requests
response with an error message. 🚫 - If the rate limit was not exceeded, it returns a
200 OK
response with the message{ message: 'Hi' }
. 👋
With this implementation, your Next.js app router API route will be protected by the rate limiting middleware, allowing a maximum of 4 requests per 5 seconds for each client IP address. 🔒
Conclusion:
Rate limiting is an essential technique for securing and optimizing your web applications, just like a friendly bouncer making sure everyone has a good time. 🕺 By following the steps outlined in this article, you can easily implement rate limiting for your Next.js app router API routes using in-memory counters. 📈 This approach is suitable for development and small-scale applications, but for production environments, it's recommended to use a more robust solution, such as a database or a dedicated rate limiting service, to ensure better scalability, persistence, and reliability. 💪
Remember, this implementation uses an in-memory counter, which means that the rate limiting will be reset when the server restarts. 🔄 Additionally, it's essential to handle the x-forwarded-for
header with caution, as it can be spoofed by malicious clients. 🕵️♂️ In a production environment, it's recommended to only trust the x-forwarded-for
header if you're running behind a trusted proxy server that you control. 🔐
Now go forth and implement rate limiting in your Next.js app router like a champ! 🏆 And remember, a little bit of rate limiting goes a long way in keeping your applications safe and sound. 🛡️
This technique has a catch, can you identify in comments and also has a solution. Let's increate engagement in comments. 😇😅
Top comments (2)
Great. I idea you can use Middleware + JWT(json web token), request api