I have been using this library in Next.js and I would like to share how to do it as I wish this information had been somewhere to save me some time.
First of all, I created a file with a function that will act as middleware in the routes I put it in. I could have put it directly in the middleware file that Next already offers, but I wanted to have more flexibility. It is important to add the keyGenerator parameter since by default the library will look at req.ip and in Next.js that field does not exist.
export function apiRateLimiter(
handler: (
req: NextRequest,
params: { params: Promise<Record<string, string>> }
) => Promise<NextResponse>
) {
return async (req: NextRequest, params: { params: Promise<Record<string, string>> }): Promise<NextResponse> => {
const limiter = rateLimit({
windowMs: 60 * 1000,
limit: 20,
standardHeaders: 'draft-7',
legacyHeaders: false,
store: new PostgresStore(
{
user: SERVER_CONFIG.ENV.DB_USER,
password: SERVER_CONFIG.ENV.DB_PASSWORD,
host: SERVER_CONFIG.ENV.DB_HOST,
database: SERVER_CONFIG.ENV.DB_NAME,
port: SERVER_CONFIG.ENV.DB_PORT,
},
'rate_limit_requests',
),
keyGenerator: (req) => {
return req.headers["x-forwarded-for"] ?? '0.0.0.0'
},
handler: (req) => {
if (req.rateLimit.remaining === 0) {
throw new Error;
}
}
})
try {
const mockRes = {
setHeader: () => {},
status: () => ({ send: () => {} })
};
await new Promise<void>((resolve, reject) => {
limiter(req, mockRes, (error: Error | undefined) => {
if (error) reject(error);
resolve();
});
});
return await handler(req, params);
} catch (error) {
return NextResponse.json({ error: "Too many requests" }, { status: 429 });
}
}
}
Using it on a route it would look something like this:
export const POST = apiRateLimiter(async (request, route) => {
...
});
On the other hand, you have to configure webpack in next.config.ts to add the migration files in the build, since if it is not done explicitly, they are not detected and therefore the schema with the tables is not generated. You need to add migrations for both @acpr/rate-limit-postgresql and postgres-migrations
import type { NextConfig } from "next";
import CopyPlugin from 'copy-webpack-plugin';
const nextConfig: NextConfig = {
webpack: (config, { isServer }) => {
if (isServer) {
config.plugins.push(
new CopyPlugin({
patterns: [
{
from: 'node_modules/postgres-migrations/dist/migrations',
to: 'vendor-chunks/migrations'
},
{
from: 'node_modules/@acpr/rate-limit-postgresql/dist/migrations',
to: 'vendor-chunks/migrations'
},
],
})
);
}
return config;
},
};
export default nextConfig;
And with this the library would already be working in Next.js, I hope it is useful to someone or it would even be nice if this info was in the documentation. I understand that this library is explicitly made for express but since Next.js uses express underneath and it is so popular today I wouldn't find it strange to see some support.
I have been using this library in Next.js and I would like to share how to do it as I wish this information had been somewhere to save me some time.
First of all, I created a file with a function that will act as middleware in the routes I put it in. I could have put it directly in the middleware file that Next already offers, but I wanted to have more flexibility. It is important to add the
keyGeneratorparameter since by default the library will look atreq.ipand in Next.js that field does not exist.Using it on a route it would look something like this:
On the other hand, you have to configure webpack in
next.config.tsto add the migration files in the build, since if it is not done explicitly, they are not detected and therefore the schema with the tables is not generated. You need to add migrations for both@acpr/rate-limit-postgresqlandpostgres-migrationsAnd with this the library would already be working in Next.js, I hope it is useful to someone or it would even be nice if this info was in the documentation. I understand that this library is explicitly made for
expressbut since Next.js uses express underneath and it is so popular today I wouldn't find it strange to see some support.