Cosa significa davvero API-first
API-first non significa "scrivere le API prima del frontend". Significa trattare l'API come il prodotto principale, non come un layer accessorio. Il contratto — endpoint, payload, errori, versioning — viene definito, revisionato e concordato prima di scrivere business logic o UI. Il codice implementa il contratto, non viceversa.
I vantaggi pratici: frontend e backend possono sviluppare in parallelo con mock; i contratti sono verificabili; le rotture breaking vengono rilevate in review, non in produzione.
Perché FastAPI si presta all'API-first
FastAPI genera automaticamente la spec OpenAPI 3.x dallo stesso codice che esegue le richieste. Non c'è disallineamento tra documentazione e implementazione perché sono la stessa cosa. Pydantic v2 definisce i tipi dei payload con validazione a runtime e serializzazione JSON inclusa — nessun layer di validazione separato da mantenere.
I principi di design che contano
Pydantic v2: la validazione come tipo
Pydantic v2 è circa 5-10x più veloce della v1 grazie al core in Rust. Per FastAPI, definire modelli Pydantic separati per input (request) e output (response) è una pratica importante: il modello di risposta decide esattamente cosa viene serializzato e inviato al client, prevenendo la fuoriuscita accidentale di campi interni (password hash, ID interni, flag di sistema).
I validator di Pydantic v2 (@field_validator, @model_validator) permettono logiche di validazione complesse che vanno oltre il tipo — regole di business, coerenza tra campi, normalizzazione dei dati in ingresso.
Dependency injection in FastAPI
Il sistema di dependency injection di FastAPI è uno dei suoi punti più sottovalutati. Le dipendenze — connessioni database, autenticazione, permessi, rate limiting — vengono dichiarate come parametri di funzione con Depends(). FastAPI le risolve automaticamente a ogni richiesta.
Il beneficio principale non è la comodità sintattica: è la testabilità. In fase di test, le dipendenze reali (DB, servizi esterni) vengono sostituite da mock tramite app.dependency_overrides, senza modificare nulla nel codice applicativo.
Testing con httpx: test senza server
FastAPI è testabile con httpx.AsyncClient e app come transport — nessun server HTTP reale necessario, zero latenza di rete, test deterministici. La struttura ideale:
- Unit test: testano singole funzioni Pydantic e business logic pura.
- Integration test con httpx: testano l'endpoint completo con dependency override per il DB (database di test, non mock).
- Contract test: verificano che lo schema OpenAPI generato non abbia breaking change rispetto alla versione precedente (tool:
openapi-diff).
Una breaking change è qualsiasi modifica che richiede aggiornamenti al codice client per continuare a funzionare: rimozione di un campo, cambio di tipo, cambio del formato di un errore, cambio dei codici HTTP. Aggiungere campi opzionali non è breaking. Cambiare il nome di un campo esistente lo è sempre. Definire in anticipo cosa è breaking e cosa non lo è — scritta nel CONTRIBUTING del progetto — salva mesi di debugging integrazioni in produzione.
Autenticazione: non reinventarla
FastAPI ha security scheme nativi per OAuth2, JWT Bearer e API key. Per API B2B, JWT con RS256 (firma asimmetrica) è lo standard: il provider genera i token firmati con la chiave privata, i consumer li verificano con la chiave pubblica senza chiamate aggiuntive al provider. Per API di servizi interni, API key con header X-API-Key è sufficiente — semplice da rotare, da revocare, da tracciare nei log.
OpenAPI come fonte di verità
La spec OpenAPI generata da FastAPI non è solo documentazione: è la fonte di verità del contratto. Usarla per generare client SDK (openapi-generator), per eseguire contract testing automatico in CI, per validare che le breaking change siano intenzionali. Un CI che fallisce quando la spec cambia in modo incompatibile è il guard rail che serve.