API Rate Limiter mit Valkey erstellen

Wenn KI beim Programmieren eingesetzt wird, steht oft die Begeisterung im Vordergrund, etwas Neues und Kreatives zu entwickeln. Dennoch sollte Sicherheit von Beginn an eine zentrale Rolle spielen. Ohne einen Security-First-Ansatz können Projekte unbeabsichtigt Schwachstellen enthalten, die Angreifer ausnutzen können. Besonders relevant ist das bei APIs, da sie durch zu viele Anfragen, Missbrauch von Rate Limits oder sogar DDoS-Angriffe belastet werden können. Wer Sicherheit früh berücksichtigt, sorgt dafür, dass eine Anwendung nicht nur innovativ, sondern auch sicher, stabil und zuverlässig ist.

Viele Entwickler kennen Situationen wie diese:

  • Ein Entwickler baut ein modernes Frontend mit React oder Next.js, vergisst jedoch die Implementierung eines API Rate Limitings.
  • Ein Team konzentriert sich auf schnelle Feature-Entwicklung, vernachlässigt aber grundlegende Sicherheitsmaßnahmen.
  • Eine Anwendung wird mit ansprechenden Animationen veröffentlicht, besitzt jedoch keinen Schutz vor DDoS-Angriffen.
  • Ein Entwickler stellt ein MVP bereit, ohne vorher zu planen, wie API-Missbrauch behandelt werden soll.

In diesem Tutorial lernst du, wie sich solche Sicherheitslücken schließen lassen, indem du mit Valkey, einer Redis-kompatiblen Datenbank, einen Rate Limiter in einer verwalteten Datenbankumgebung aufbaust.

Was ist ein Rate Limiter?

Ein Rate Limiter ist ein Mechanismus, der steuert, wie viele Anfragen ein Nutzer oder Client innerhalb eines festgelegten Zeitfensters an eine API senden darf. Er funktioniert wie eine Art Zugangskontrolle, überwacht den eingehenden Traffic und setzt definierte Grenzwerte durch, um Missbrauch zu reduzieren.

Vorteile von Rate Limiting

  • Schutz vor Missbrauch: Es hilft dabei, zu verhindern, dass böswillige Nutzer ein System mit übermäßig vielen Anfragen überlasten.
  • DDoS-Abwehr: Es unterstützt den Schutz vor Distributed-Denial-of-Service-Angriffen, indem das Anfragevolumen begrenzt wird.
  • Ressourcenmanagement: Es sorgt dafür, dass Anwendungsressourcen fair auf alle Nutzer verteilt werden.
  • Kostenkontrolle: Es kann Infrastrukturkosten senken, indem unnötige Traffic-Spitzen vermieden werden.
  • API-Stabilität: Es trägt zu gleichbleibender Performance bei, da Serverüberlastungen verhindert werden.

Genau hier ist Valkey hilfreich. Durch seine In-Memory-Datenstrukturen und atomaren Operationen eignet es sich sehr gut für schnelles und zuverlässiges Rate Limiting.

Was wird in diesem Tutorial gebaut?

Du erstellst einen API Rate Limiter mit der Chuck Norris Jokes API. Wenn jemand die Anwendung öffnet, kann diese Person innerhalb eines Zeitfensters von 60 Sekunden bis zu fünfmal einen zufälligen Chuck-Norris-Witz über die API abrufen. Bei jeder Anfrage speichert das System die IP-Adresse des Nutzers und zählt die Anfrage. Wird innerhalb derselben Minute eine sechste Anfrage gestellt, erhält der Nutzer stattdessen die Meldung „Rate limit exceeded. Please wait a minute“. Nach Ablauf der 60 Sekunden wird der Zähler zurückgesetzt und es können wieder neue Witze abgefragt werden.

Voraussetzungen

  • Zugriff auf eine verwaltete Valkey-Datenbank.
  • Grundlegendes Verständnis von REST APIs und HTTP-Methoden.
  • Vertrautheit mit den Konzepten von Valkey.
  • Grundkenntnisse in Next.js für den Aufbau des Frontends. Alternativ kann das Frontend auch mit Vanilla JavaScript erstellt oder die Lösung lokal mit curl getestet werden.

So funktioniert der Rate Limiter

Bevor der Code geschrieben und der Rate Limiter umgesetzt wird, ist es sinnvoll zu verstehen, wie Anfragen verarbeitet werden und wie das Backend damit umgeht.

Die Rate-Limiter-Anwendung besteht aus drei Hauptkomponenten, die zusammenarbeiten:

  • Das Frontend: Dies ist der Teil der Anwendung, mit dem Nutzer interagieren. Es zeigt an, wie viele Anfragen an die API gestellt werden, gibt den von der Joke API zurückgegebenen Witz aus und zeigt eine Fehlermeldung an, wenn das Rate Limit erreicht ist.
  • Das Backend: Es übernimmt die Rolle einer Traffic-Steuerung. Es verarbeitet Anfragen und wendet die Rate-Limiting-Logik an.
  • Valkey: Valkey dient als Tracker für das Rate Limit. Es zählt Anfragen über atomare Operationen, entfernt alte Zähler automatisch per TTL-basierter Ablaufzeit und führt diese Vorgänge sehr schnell aus, da es im Arbeitsspeicher läuft.

Eine verwaltete Valkey-Datenbank erstellen

  1. Da Valkey die Logik für den Rate Limiter übernimmt, besteht der erste Schritt darin, eine Valkey-Datenbank zu erstellen:
  2. Melde dich in deinem Cloud- oder Hosting-Control-Panel an, öffne den Datenbankbereich und erstelle eine neue Datenbank.
  3. Um einen Datenbank-Cluster zu erstellen, wählst du eine passende Region aus und legst Valkey als Datenbank-Engine fest.
  4. Wähle einen Tarif, der zu deinen Anforderungen passt, und erstelle anschließend den Datenbank-Cluster.
  5. Nachdem die Datenbank bereitgestellt wurde, werden die Verbindungsdaten angezeigt. Für die Verbindung zu Valkey benötigst du Port, Passwort und Host-URL. Je nach Plattform kannst du außerdem Übersichtsseiten, Einblicke, Logs und Einstellungen über separate Tabs einsehen.

Backend erstellen

Nachdem die Valkey-Datenbank erstellt wurde, folgt der Aufbau eines Express.js-Backends, das sich mit Valkey verbindet und den Rate Limiter implementiert.

Um die Verbindung zur Valkey-Datenbank herzustellen, erstellst du eine .env-Datei mit den Valkey-Zugangsdaten aus deinem Datenbank-Control-Panel:

VALKEY_HOST=your-db-host.example.com
VALKEY_PORT=25061
VALKEY_PASSWORD=your-password

Erstelle anschließend die zentrale Datei index.js und richte die Valkey-Verbindung ein:

const fetch = (...args) => import('node-fetch').then(({ default: fetch }) => fetch(...args));

require('dotenv').config();

const express = require('express');

const Redis = require('ioredis');

const cors = require('cors');

const app = express();

app.use(cors());

const PORT = process.env.PORT || 3001;

// Create Redis-compatible Valkey client

const redis = new Redis({

  host: process.env.VALKEY_HOST,

  port: Number(process.env.VALKEY_PORT),

  password: process.env.VALKEY_PASSWORD,

  tls: {}, // Required when the managed Valkey service uses secure connections

});

Die Konfiguration tls: {} ist wichtig, wenn die verwaltete Valkey-Umgebung eine sichere Verbindung voraussetzt.

Als Nächstes wird ein Lua-Skript für atomare Operationen verwendet, damit das Rate Limiting thread-sicher bleibt:

// Lua script for atomic rate limiting
const rateLimiterLuaScript = `
  local current
  current = redis.call("INCR", KEYS[1])
  if tonumber(current) == 1 then
    redis.call("EXPIRE", KEYS[1], ARGV[1])
  end
  return current
`;

// Rate limiter middleware
const rateLimiter = async (req, res, next) => {
  const ip = req.ip || 'global';
  const limit = 5;
  const windowInSeconds = 60;
  const key = `rate:${ip}`;

  try {
    const current = await redis.eval(rateLimiterLuaScript, 1, key, windowInSeconds);
    console.log(`[RateLimit] IP: ${ip} - Count: ${current}`);

    if (current > limit) {
      return res.status(429).send('🚫 Rate limit exceeded. Please wait a minute.');
    }

    next();
  } catch (err) {
    console.error('[Valkey error]', err);
    res.status(500).send('Valkey error');
  }
};

Diese Middleware übernimmt folgende Aufgaben:

  • Sie verfolgt Anfragen anhand der IP-Adresse.
  • Sie erlaubt fünf Anfragen pro Minute.
  • Sie nutzt atomare Operationen, um Race Conditions zu vermeiden.
  • Sie lässt Zähler nach 60 Sekunden automatisch ablaufen.

Nun wird der API-Endpunkt erstellt, der durch das Rate Limit geschützt ist. In diesem Beispiel verwendet der Endpunkt die Chuck Norris Jokes API:

// Chuck Norris joke route with rate limiting
app.get('/api/joke', rateLimiter, async (req, res) => {
  console.log("✅ Incoming request to /api/joke");

  try {
    const response = await fetch('https://api.chucknorris.io/jokes/random');
    const data = await response.json();
    console.log("✅ Joke fetched:", data.value);
    res.send(data.value);
  } catch (err) {
    console.error("❌ Failed to fetch joke:", err);
    res.status(500).send('Failed to fetch joke');
  }
});

Das Backend ist damit vorbereitet, Anfragen mit Rate Limiting zu verarbeiten. Im nächsten Abschnitt wird das Frontend erstellt, damit es mit dieser API interagieren kann.

Frontend erstellen

Sobald das Backend läuft, besteht der nächste Schritt darin, ein Frontend zu erstellen, das die Funktion sichtbar macht. In diesem Abschnitt geht es um die zentrale Integration mit der Backend-API.

Integration von Frontend und Backend

Die folgende Hauptseiten-Komponente übernimmt die Kommunikation mit dem rate-limitierten Backend:

// pages/index.js
import { useState } from 'react';

export default function Home() {
  const [joke, setJoke] = useState('');
  const [error, setError] = useState('');
  const [loading, setLoading] = useState(false);

  const fetchJoke = async () => {
    setLoading(true);
    setError('');
    try {
      // Send a request to the rate-limited backend
      const response = await fetch('http://localhost:3001/api/joke');
      
      // Handle the rate limit response with status code 429
      if (response.status === 429) {
        setError('🚫 Too many requests! Please wait a minute.');
        return;
      }
      
      // Handle a successful response
      const data = await response.text();
      setJoke(data);
    } catch (err) {
      setError('Failed to fetch joke. Please try again.');
    } finally {
      setLoading(false);
    }
  };

  return (

 

 

 

Chuck Norris Joke Generator

 

{error &&

 

{error}

 

} {joke &&

 

{joke}

 

}

 

); }

So funktioniert die Anwendung

Wenn ein Nutzer auf den Button „Get a Joke“ klickt, sendet das Frontend eine Anfrage an die Backend-API. Das Backend prüft das Rate Limit in Valkey. Liegt der Nutzer noch innerhalb der Grenze von fünf Anfragen pro Minute, gibt die Anwendung einen Chuck-Norris-Witz zurück. Wurde das Limit bereits überschritten, erhält der Nutzer eine freundliche Meldung zu zu vielen Anfragen. Das Frontend verarbeitet die Antworten, zeigt während der Anfrage einen Ladezustand an, gibt passende Fehlermeldungen aus, wenn etwas fehlschlägt, und verwaltet den Anwendungsstatus für den aktuellen Witz, mögliche Fehler und den Ladezustand.

Warum Valkey verwenden?

Valkey kann als moderne Redis-kompatible Option für verwaltete Caching- und In-Memory-Datenbank-Workloads eingesetzt werden. Die folgenden Punkte zeigen, wie Valkey den Rate Limiter unterstützt:

1. Verbesserte Unterstützung und Funktionen

Valkey basiert auf einem Redis-Fork und bringt mehrere Verbesserungen mit:

  • Eine neue Dictionary-Struktur mit experimenteller RDMA-Unterstützung für bessere Speichereffizienz.
  • Verbesserte Multi-Threading-Funktionen für höhere Skalierbarkeit.
  • Bessere Observability mit Per-Slot-Metriken.
  • Dual-Channel-Replikation für geringere Latenz bei der Synchronisierung.

Der Rate Limiter profitiert von diesen Möglichkeiten über die Verbindungskonfiguration:

const redis = new Redis({
  host: process.env.VALKEY_HOST,
  port: Number(process.env.VALKEY_PORT),
  password: process.env.VALKEY_PASSWORD,
  tls: {}, // Required when the managed Valkey service uses secure connections
});

2. Performance-Vorteile

Valkeys Multi-Threading-Funktionen sind für Rate Limiting nützlich. Wenn mehrere Nutzer gleichzeitig auf die API zugreifen, kann Valkey parallele Anfragen effizient verarbeiten:

const rateLimiterLuaScript = `
  local current
  current = redis.call("INCR", KEYS[1])
  if tonumber(current) == 1 then
    redis.call("EXPIRE", KEYS[1], ARGV[1])
  end
  return current
`;

Dieses Lua-Skript wird atomar ausgeführt. Die verbesserte Threading-Unterstützung von Valkey hilft dabei, viele dieser Operationen gleichzeitig zu verarbeiten, ohne die Performance zu beeinträchtigen.

3. Speichereffizienz

Die Dictionary-Struktur von Valkey trägt dazu bei, den Rate Limiter speichereffizienter zu machen. Jeder Rate-Limit-Zähler wird mit geringem Overhead gespeichert:

const key = `rate:${ip}`;
const windowInSeconds = 60;

Durch die Kombination aus effizienter Speichernutzung und automatischem Ablauf per TTL kann der Rate Limiter Millionen eindeutiger IP-Adressen verwalten, ohne übermäßig viel Speicher zu verbrauchen.

4. Bessere Observability

Die Observability-Verbesserungen von Valkey erleichtern die Überwachung der Rate-Limiter-Performance. Die folgenden Metriken können verfolgt werden:

  • Die Anzahl der rate-limitierten Anfragen.
  • Die Speichernutzung pro Rate-Limit-Zähler.
  • Die Latenz der Rate-Limit-Prüfungen.

Das ist im Logging sichtbar:

console.log(`[RateLimit] IP: ${ip} - Count: ${current}`);

5. Migrationspfad

Für Umgebungen, die bereits verwaltete Caching-Dienste nutzen, kann Valkey einen praktischen Migrationspfad bieten. Die Rate-Limiter-Implementierung kann mit ähnlichen Redis-kompatiblen Diensten kompatibel bleiben, was den Wechsel erleichtert:

// Works with Redis-compatible managed caching services and Valkey
const redis = new Redis({
  host: process.env.VALKEY_HOST,
  port: Number(process.env.VALKEY_PORT),
  password: process.env.VALKEY_PASSWORD,
  tls: {}, // Required when the managed service uses secure connections
});

Zusammen machen diese Punkte Valkey zu einer starken Option für den Aufbau eines skalierbaren und effizienten Rate Limitings in Produktionsumgebungen.

FAQ

Was ist Valkey und wie funktioniert es?

Valkey ist ein Dienst, der eine skalierbare und effiziente Umsetzung von Rate Limiting ermöglichen kann. Es kombiniert atomare Operationen mit einer effizienten Dictionary-Struktur, um Rate-Limit-Zähler zu speichern. Dadurch können Millionen eindeutiger IP-Adressen verarbeitet werden, ohne übermäßig viel Speicher zu verbrauchen.

Wie hilft Valkey beim Aufbau eines skalierbaren Rate Limiters?

Valkey unterstützt den Aufbau eines skalierbaren Rate Limiters, indem es viele Anfragen ohne Performance-Verlust verarbeitet. Atomare Operationen sorgen dafür, dass Rate-Limit-Prüfungen auch in Umgebungen mit hohem Traffic korrekt und effizient bleiben. Unterstützt wird dies durch effiziente Speichernutzung und automatisches Ablaufen per TTL, wodurch Millionen eindeutiger IP-Adressen verwaltet werden können, ohne zu viel Speicher zu beanspruchen.

Welche Vorteile bietet Valkey für Rate Limiting?

Valkey bietet mehrere wichtige Vorteile für Rate Limiting. Erstens unterstützt es eine verbesserte Skalierbarkeit und eignet sich damit für viele Anfragen ohne Performance-Probleme in stark frequentierten Umgebungen. Die Speichereffizienz hält Rate-Limit-Zähler schlank, sodass Millionen eindeutiger IP-Adressen verwaltet werden können, ohne zu viel Speicher zu nutzen. Zusätzlich liefern die Observability-Funktionen von Valkey Einblicke in die Performance des Rate Limiters, darunter die Anzahl rate-limitierter Anfragen, die Speichernutzung pro Zähler und die Latenz von Rate-Limit-Prüfungen. Diese Informationen erleichtern Monitoring und Optimierung. Weitere Informationen zu den Funktionen von Valkey und ihrem Nutzen für Anwendungen findest du in der Valkey-Dokumentation.

Kann Valkey mit Managed Caching und Valkey-Diensten verwendet werden?

Ja, Valkey kann mit verwalteten Caching- und Valkey-Diensten verwendet werden. Die Implementierung kann so gestaltet werden, dass sie mit beiden Servicetypen kompatibel bleibt und dadurch einen reibungslosen Wechsel unterstützt. Diese Kompatibilität ermöglicht es Nutzern, die Funktionen von Valkey zu verwenden, ohne sich auf eine bestimmte Infrastruktur festlegen zu müssen. Unabhängig davon, ob bereits ein verwalteter Caching-Dienst genutzt wird oder eine Migration zu Valkey geplant ist, kann die Rate-Limiter-Implementierung konsistent und wirksam bleiben. Dadurch eignet sie sich gut für Traffic-Management und eine stabile Nutzererfahrung.

Wie unterstützt Valkey Speichereffizienz beim Rate Limiting?

Valkey unterstützt Speichereffizienz beim Rate Limiting durch eine effiziente Dictionary-Struktur zur Speicherung von Rate-Limit-Zählern. Diese Struktur hält den Overhead niedrig, sodass Millionen eindeutiger IP-Adressen verarbeitet werden können, ohne zu viel Speicher zu verbrauchen.

Welche Observability-Funktionen bietet Valkey für Rate Limiting?

Die Observability-Funktionen von Valkey für Rate Limiting sind darauf ausgelegt, einen besseren Überblick über die Performance des Rate Limiters zu geben. Dazu gehören:

  • Erfassung der Anzahl rate-limitierter Anfragen: Diese Metrik hilft zu erkennen, wie häufig Anfragen begrenzt werden, sodass Rate Limits bei Bedarf angepasst werden können.
  • Speichernutzung pro Rate-Limit-Zähler: Diese Information hilft dabei zu überwachen, wie viel Speicher jeder Zähler verwendet, und stellt sicher, dass der Rate Limiter keine übermäßigen Ressourcen verbraucht.
  • Latenz der Rate-Limit-Prüfungen: Die Messung der Prüflatenz hilft, Performance-Engpässe zu erkennen und den Rate Limiter für schnellere Antwortzeiten zu optimieren.

Diese Observability-Funktionen liefern nützliche Einblicke in die Performance des Rate Limiters und unterstützen datenbasierte Entscheidungen zur Optimierung des Traffic-Managements einer Anwendung. Weitere Informationen zu den Observability-Funktionen von Valkey findest du in der Valkey-Dokumentation.

Fazit

In diesem Tutorial hast du einen API Rate Limiter mit Valkey erstellt. Das zeigt, wie APIs vor Missbrauch geschützt werden können, während gleichzeitig eine gute Nutzererfahrung erhalten bleibt. Du hast gelernt, wie Rate Limiting mit atomaren Operationen von Valkey umgesetzt wird und wie sich die Backend-Logik mit einem einfachen Frontend verbinden lässt.

Quelle: digitalocean.com

Jetzt 200€ Guthaben sichern

Registrieren Sie sich jetzt in unserer ccloud³ und erhalten Sie 200€ Startguthaben für Ihr Projekt.

Das könnte Sie auch interessieren:

Moderne Hosting Services mit Cloud Server, Managed Server und skalierbarem Cloud Hosting für professionelle IT-Infrastrukturen

ArgoCD ApplicationSets für Multi-Cluster Kubernetes

Kubernetes, Tutorial
Vijonavor 3 Stunden Multi-Cluster-Kubernetes-Deployments mit ArgoCD ApplicationSets verwalten Der Betrieb von Anwendungen über mehrere Kubernetes-Cluster hinweg kann in produktiven Umgebungen für Entwicklungs- und Betriebsteams schnell anspruchsvoll werden. Die Auslieferung kann sich…
Moderne Hosting Services mit Cloud Server, Managed Server und skalierbarem Cloud Hosting für professionelle IT-Infrastrukturen

Model Context Protocol mit OpenAI Agents: Praxisleitfaden

AI/ML, Tutorial
VijonaHeute um 11:34 Uhr Model Context Protocol und OpenAI Agents: Praxisleitfaden für agentenbasierte KI-Workflows Workflows auf Basis großer Sprachmodelle haben sich von einer optionalen Erweiterung zu einem wichtigen Bestandteil moderner agentenbasierter…
Moderne Hosting Services mit Cloud Server, Managed Server und skalierbarem Cloud Hosting für professionelle IT-Infrastrukturen

Apriel-1.5-15B-Thinker: Multimodales KI-Modell erklärt

AI/ML, Tutorial
VijonaHeute um 10:06 Uhr ServiceNow Apriel-1.5-15B-Thinker: Überblick über ein multimodales Reasoning-Modell Besonders interessant an ServiceNows neuem multimodalen Reasoning-Modell Apriel-1.5-15B-Thinker ist der klare Schwerpunkt auf Midtraining, anstatt stark auf Post-Training und Reinforcement…