Come iniziare

Rate Limiting

Rate limiting e best practices per l'utilizzo dell'API
Il rate limiting generale per gli endpoint API non è ancora implementato. Questa pagina descrive le best practices consigliate per quando verrà implementato e il rate limiting attualmente disponibile per endpoint specifici.

Rate Limiting Attualmente Implementato

Reset Password

L'endpoint di reset password implementa rate limiting per prevenire abusi:

  • Limite: 3 tentativi per ora per email
  • Finestra: 1 ora
  • Errore: Restituisce 429 Too Many Requests con codice RATE_LIMIT_ERROR quando il limite viene superato
{
  "status": "error",
  "error": {
    "code": "RATE_LIMIT_ERROR",
    "message": "Troppi tentativi di reset password. Riprova più tardi.",
    "details": {}
  }
}

Rate Limiting Generale (Pianificato)

Il rate limiting generale per tutti gli endpoint API è pianificato per una futura versione. I limiti previsti sono indicati di seguito come riferimento.

Limiti Pianificati

I limiti di rate previsti variano in base al tipo di autenticazione:

Tipo AutenticazioneLimite PianificatoFinestra
PASETO Token (utenti)100 richieste/minutoPer utente
API Key1000 richieste/minutoPer chiave

Headers Pianificati

Quando implementato, ogni risposta includerà header informativi sui limiti:

X-RateLimit-Limit: 100
X-RateLimit-Remaining: 95
X-RateLimit-Reset: 1642248000
Retry-After: 60

Gestione Rate Limit Exceeded (Pianificato)

Quando implementato, superando il limite riceverai una risposta 429 Too Many Requests:

{
  "status": "error",
  "error": {
    "code": "RATE_LIMIT_EXCEEDED",
    "message": "Troppe richieste. Riprova più tardi.",
    "details": {
      "retryAfter": 60,
      "limit": 100,
      "remaining": 0,
      "resetAt": "2024-01-15T10:31:00.000Z"
    }
  },
  "meta": {
    "requestId": "uuid-unico",
    "timestamp": "2024-01-15T10:30:00.000Z"
  }
}

Best Practices Consigliate

Anche se il rate limiting generale non è ancora implementato, è consigliabile seguire queste best practices per prepararsi all'implementazione futura e per essere buoni cittadini dell'API:

1. Implementa Exponential Backoff

Quando ricevi un errore 429 (attualmente solo per reset password), implementa un backoff esponenziale:

async function makeRequestWithRetry(url: string, options: RequestInit, maxRetries = 3) {
  for (let attempt = 0; attempt < maxRetries; attempt++) {
    try {
      const response = await fetch(url, options);

      if (response.status === 429) {
        const data = await response.json();
        const retryAfter = data.error?.details?.retryAfter || Math.pow(2, attempt) * 1000;

        console.log(`Rate limited. Retrying after ${retryAfter}ms`);
        await sleep(retryAfter);
        continue;
      }

      return response;
    } catch (error) {
      if (attempt === maxRetries - 1) throw error;
      await sleep(Math.pow(2, attempt) * 1000);
    }
  }
}

2. Monitora Header di Rate Limit (Quando Disponibile)

Quando il rate limiting sarà implementato, controlla sempre gli header per sapere quanti request ti rimangono:

const response = await fetch(url, options);
const remaining = parseInt(response.headers.get("X-RateLimit-Remaining") || "0");

if (remaining < 10) {
  // Riduci la frequenza delle richieste
  await sleep(1000);
}

3. Usa Caching Quando Possibile

Riduci le richieste usando cache per dati che cambiano raramente:

const cache = new Map();

async function getCachedData(key: string, ttl: number, fetcher: () => Promise<any>) {
  const cached = cache.get(key);

  if (cached && Date.now() - cached.timestamp < ttl) {
    return cached.data;
  }

  const data = await fetcher();
  cache.set(key, { data, timestamp: Date.now() });
  return data;
}

4. Batch Requests Quando Possibile

Invece di fare molte richieste singole, usa endpoint batch quando disponibili:

// ❌ Male: molte richieste
for (const id of ids) {
  await fetch(`/api/v1/organizations/${id}`);
}

// ✅ Meglio: una richiesta batch
await fetch("/api/v1/organizations/batch", {
  method: "POST",
  body: JSON.stringify({ ids }),
});

5. Implementa Request Queuing

Per applicazioni che fanno molte richieste, implementa una coda:

class RequestQueue {
  private queue: Array<() => Promise<any>> = [];
  private processing = false;
  private rateLimit = 100; // richieste per minuto
  private interval = 60000; // 1 minuto

  async add(request: () => Promise<any>) {
    return new Promise((resolve, reject) => {
      this.queue.push(async () => {
        try {
          const result = await request();
          resolve(result);
        } catch (error) {
          reject(error);
        }
      });
      this.process();
    });
  }

  private async process() {
    if (this.processing) return;
    this.processing = true;

    const startTime = Date.now();
    let requestCount = 0;

    while (this.queue.length > 0) {
      if (requestCount >= this.rateLimit) {
        const elapsed = Date.now() - startTime;
        const waitTime = Math.max(0, this.interval - elapsed);
        await sleep(waitTime);
        requestCount = 0;
      }

      const request = this.queue.shift();
      if (request) {
        await request();
        requestCount++;
      }
    }

    this.processing = false;
  }
}

Strategie per Tipi di Applicazione

Applicazioni Web (Frontend)

  • Usa debouncing per input utente
  • Implementa caching lato client
  • Pre-carica dati quando possibile
  • Usa WebSockets per aggiornamenti real-time quando disponibili

Script e Automazioni

  • Distribuisci richieste nel tempo
  • Usa sleep tra batch di richieste
  • Implementa retry con backoff esponenziale
  • Considera di eseguire durante orari di basso traffico

Integrazioni Server-to-Server

  • Usa API Keys con scope appropriati
  • Implementa caching lato server
  • Usa webhook quando disponibili invece di polling
  • Monitora header di rate limit

Monitoraggio (Consigliato)

Anche se il rate limiting generale non è ancora implementato, è buona pratica monitorare le tue richieste:

class RateLimitMonitor {
  private requests: number[] = [];

  recordRequest() {
    const now = Date.now();
    this.requests.push(now);
    // Rimuovi richieste più vecchie di 1 minuto
    this.requests = this.requests.filter((time) => now - time < 60000);
  }

  getRemainingRequests(limit: number): number {
    return Math.max(0, limit - this.requests.length);
  }

  getTimeUntilReset(): number {
    if (this.requests.length === 0) return 0;
    const oldest = Math.min(...this.requests);
    return Math.max(0, 60000 - (Date.now() - oldest));
  }
}

Note

  • Il rate limiting è attualmente implementato solo per l'endpoint di reset password
  • Il rate limiting generale per tutti gli endpoint è pianificato per una futura versione
  • Le best practices descritte sono consigliate per prepararsi all'implementazione futura
  • Seguire queste pratiche aiuta a essere buoni cittadini dell'API anche senza limiti forzati

Prossimi Passi