Limitation de débit

Une fenêtre fixe : chaque clé a un compteur qui se réinitialise après la fenêtre. check(clé, { max, windowSecs }) renvoie autorisé / restant / retry-after. Ici une rafale de 6 requêtes contre une limite de 3 — les 3 premières passent, les suivantes sont bloquées avec un délai de ré-essai.

Astuce
En production, dérivez la clé avec keyForRequest(request, bucket) (IP client + nom de bucket) et adossez un store partagé entre workers. attempt(clé, opts, fn) exécute fn seulement si sous la limite ; reset(clé) efface le compteur (ex. après une connexion réussie).

Lancez la rafale pour voir la limite s'appliquer.

src/app/examples/rate-limit/page.tsxTSX
import { createRateLimiter, memoryRateStore, keyForRequest } from "@bext-stack/framework/rate-limit";

const limiter = createRateLimiter({ store: memoryRateStore() });

export async function action({ request }) {
  const key = keyForRequest(request, "signup");   // client ip + bucket
  const r = await limiter.check(key, { max: 5, windowSecs: 60 });
  if (!r.allowed) {
    return new Response("Too many requests", {
      status: 429, headers: { "retry-after": String(r.retryAfterSecs) },
    });
  }
  // …handle the request…
}