Inhaltsverzeichnis
- Verwendeter Stack
- Zwei neue NPM Pakete
- Erste Schritte mit der Redis-Datenbank
- Einloggen und Erstellen der Redis DB
- Umgebungsvariablen hinzufügen (.env.local)
- Implementieren der Ratenbegrenzung in eine bestehende API Route
- Definieren des "Ratenbegrenzer"
- Kontrolle der Ratenbegrenzung
- Fehlermeldung
- Optimierung erforderlich für GlobalRatelimit
- Cloudapp-dev und bevor Sie uns verlassen
Sicherzustellen, dass ein System verfügbar ist, ist für jedes Produkt von entscheidender Bedeutung. Missbrauch kann jedoch die Ressourcen überlasten, oder es kann notwendig sein, die Nutzung zu kontrollieren und Gebühren zu erheben. Eine effektive Implementierung von Ratenbegrenzungen löst diese Probleme und kann nahtlos integriert werden. Da Ihr System bereits vorhanden ist, benötigen Sie eine Lösung, die in zustandslosen Umgebungen wie serverlosen Funktionen gut funktioniert, ohne zusätzliche Entwicklungszeit zu erfordern.
Hier ist das GitHub repo mit dem vollständigen Code, in dem Sie die beiden neuen Komponenten sehen können.
Beispielseite (Gehostet auf Vercel -> https://nextjs14-azureb2c-prisma.vercel.app/
Verwendeter Stack
Ich werde mit meinem Standard-Stack beginnen:
Next.js 14 als das Web-Framework (API Routes)
Upstash Redis, in Kombination mit den NPM Paketen @upstash/ratelimit und @upstash/redis
Vercel für das Hosting
Zwei neue NPM Pakete
@upstash/ratelimit - Implementiert bisher drei verschiedene standardisierte Algorithmen, und Sie können mehr darüber im Projekt lesen.README.
@upstash/redis - Wird für Lese und Schreibzugriffe auf die REDIS DB verwendet
npm install @upstash/ratelimit @upstash/redisErste Schritte mit der Redis-Datenbank
Ratenbegrenzung mit einer einzigen Datenbank ist einfach zu implementieren. Beginnen Sie mit der Erstellung einer neuen Redis-Datenbank auf Upstash:
Einloggen und Erstellen der Redis DB



Umgebungsvariablen hinzufügen (.env.local)
Die zuvor kopierten Variablen werden jetzt verwendet
# Redis Upstash
UPSTASH_REDIS_REST_URL="https://xxxxx.upstash.io"
UPSTASH_REDIS_REST_TOKEN="xxxx"Implementieren der Ratenbegrenzung in eine bestehende API Route
Gehen wir zu einem bestehenden API-Router. Ich werde den Sitemap-Zähler verwenden, den ich in einem vorherigen Post erstellt habe.
import { NextRequest, NextResponse } from "next/server";
import { getSitemapEntries } from "@/lib/sitemapcounter";
import { Ratelimit } from "@upstash/ratelimit";
import { Redis } from "@upstash/redis";
// Create a new ratelimiter, that allows 1 requests per 45 seconds
const ratelimit = new Ratelimit({
redis: Redis.fromEnv(),
limiter: Ratelimit.slidingWindow(1, "45 s"),
});
export async function GET(request: NextRequest) {
const { searchParams } = new URL(request.url);
const url = searchParams.get("url");
// Use a constant string to limit all requests with a single ratelimit
// Or use a userID, apiKey or ip address for individual limits.
const identifier = "sitemapcounter";
const { success } = await ratelimit.limit(identifier);
if (!success) {
console.log("Unable to process at this time");
return NextResponse.json({ error: "Quota exceeded" }, { status: 429 });
}
if (!url) {
return NextResponse.json({ error: "URL is required" }, { status: 400 });
}
const entries = await getSitemapEntries(url);
if (entries !== null) {
return NextResponse.json({ entries: entries || 0 });
} else {
return NextResponse.json(
{ error: "Failed to fetch or parse sitemap" },
{ status: 500 }
);
}
// Alternatively, you could return a 202 Accepted status code
return new NextResponse(null, { status: 202 });
}Definieren des "Ratenbegrenzer"
In diesem Abschnitt definieren wir die Ratenbegrenzung und legen fest, dass nur ein Aufruf innerhalb von 45 Sekunden erlaubt ist.
// Create a new ratelimiter, that allows 1 requests per 45 seconds
const ratelimit = new Ratelimit({
redis: Redis.fromEnv(),
limiter: Ratelimit.slidingWindow(1, "45 s"),
});Kontrolle der Ratenbegrenzung
Als nächsten Schritt definieren wir einen Bezeichner (der die öffentliche IP-Adresse, eine Benutzer-ID (für angemeldete Benutzer) usw. sein könnte).
// Use a constant string to limit all requests with a single ratelimit
// Or use a userID, apiKey or ip address for individual limits.
const identifier = "sitemapcounter";
const { success } = await ratelimit.limit(identifier);
if (!success) {
console.log("Unable to process at this time");
return NextResponse.json({ error: "Quota exceeded" }, { status: 429 });
}Fehlermeldung
Wenn die Kontrolle fehl schlägt, dann wird ein Fehler "Quote überschritten" ausgegeben.

Optimierung erforderlich für GlobalRatelimit
Für Projekte in größerem Maßstab können Sie ein "GlobalRateLimit" mit über den Globus verteilten Knoten definieren.
import { GlobalRatelimit } from "@upstash/ratelimit"; import { Redis } from "@upstash/redis";// Create a new ratelimiter, that allows 10 requests per 10 seconds
const ratelimit = new GlobalRatelimit({
redis: [
new Redis({
/* europe */
}),
new Redis({
/* north america */
}),
],
limiter: Ratelimit.slidingWindow(10, "10 s"),
});Wie Sie sehen können, ist die Integration einfach. Der gleiche Ansatz kann für ein Abrechnungsmodell verwendet werden, bei dem der Kunde für eine bestimmte Anzahl von API-Aufrufen bezahlt.
Cloudapp-dev und bevor Sie uns verlassen
Danke, dass Sie bis zum Ende gelesen haben. Noch eine Bitte bevor Sie gehen:




