L’interesse di ricerca per “REST vs GraphQL” è rimasto costantemente elevato per tutti gli anni 2020, con il dibattito che ha guadagnato urgenza rinnovata man mano che sempre più team costruiscono prodotti fortemente orientati al frontend con requisiti di dati complessi. GraphQL è in produzione da quando Facebook l’ha reso open source nel 2015 ed è ora maturo, ben attrezzato e genuinamente adottato su larga scala. Eppure REST rimane la scelta dominante per le nuove API nel 2026, e non senza ragione. La domanda non è quale sia teoricamente migliore, ma quale si adatti al tuo progetto.
Questa guida copre cosa sia effettivamente ogni approccio, le differenze tecniche fondamentali con un esempio di codice concreto, le realtà delle prestazioni che il marketing non menziona, le considerazioni di sicurezza che cambiano il calcolo, e una raccomandazione chiara per ogni tipo di scenario. Alla fine avrai un framework decisionale piuttosto che un altro confronto non conclusivo.
TL;DR
- REST è l’impostazione predefinita giusta per la maggior parte dei progetti nel 2026: più semplice da implementare, più facile da documentare, migliore caching HTTP, e ampiamente compreso dai consumatori esterni
- GraphQL giustifica la sua complessità quando hai un grafo di dati genuinamente complesso, più client con esigenze di dati diverse, o un team frontend che deve iterare senza modifiche backend
- Il problema delle query N+1 di GraphQL e le sfide di caching sono costi di produzione reali che la maggior parte dei confronti sottovaluta; pianifica DataLoader e query persistenti fin dal primo giorno
- Se stai costruendo un’API pubblica per sviluppatori terzi, REST vince in scopribilità e disponibilità degli strumenti; GraphQL eccelle per API interne dove controlli entrambe le estremità
Cosa sia effettivamente REST
REST (Representational State Transfer) è uno stile architetturale, non un protocollo. Roy Fielding lo ha definito nella sua tesi di dottorato del 2000 come un insieme di vincoli per i sistemi ipermedia distribuiti. In pratica, un’API RESTful significa: comunicazione stateless via HTTP, URL orientate alle risorse, verbi HTTP standard (GET, POST, PUT, PATCH, DELETE) per indicare l’intento, e codici di stato HTTP standard per comunicare i risultati.
Un endpoint REST per una risorsa utente assomiglia a GET /api/v1/users/123. Il server restituisce una rappresentazione di quella risorsa. Il client non dice al server quali campi vuole; il server decide cosa includere nella risposta. L’API è versionata nell’URL (/v1/, /v2/) quando le modifiche incompatibili lo richiedono.
Cosa REST non è: uno standard con una specifica formale. Due API REST possono comportarsi in modo molto diverso pur essendo entrambe tecnicamente “RESTful.” Ecco perché OpenAPI (in precedenza Swagger) è diventato il layer de facto di documentazione e validazione per le API REST. Non è obbligatorio, ma una specifica OpenAPI ben mantenuta è la cosa più vicina a un contratto formale che REST abbia.
Cosa sia effettivamente GraphQL
GraphQL è un linguaggio di query per le API e un runtime per eseguire quelle query. La distinzione chiave da REST è che il client specifica esattamente quali dati vuole, non il server. Un singolo endpoint GraphQL (tipicamente POST /graphql) accetta query scritte nel linguaggio di query GraphQL e restituisce precisamente i campi richiesti.
GraphQL richiede uno schema tipizzato che descriva ogni tipo nel modello di dati e ogni query, mutazione e abbonamento disponibili. Questo schema è il contratto tra client e server. L’introspezione consente ai client di interrogare lo schema stesso per scoprire cosa è disponibile, il che alimenta un eccellente tooling per gli sviluppatori.
Sviluppato da Facebook per risolvere le sfide di recupero dati della loro app mobile nel 2012, è stato reso open source nel 2015 ed è ora governato dalla GraphQL Foundation. I principali utenti includono GitHub, Shopify, Twitter e Airbnb. È una tecnologia matura, collaudata in produzione con un ecosistema robusto.
Le differenze fondamentali spiegate
Recupero dati
REST restituisce l’intera rappresentazione della risorsa definita dal server. Se l’endpoint /api/users/123 restituisce 20 campi e ne hai bisogno solo di 3, ricevi tutti e 20. GraphQL restituisce esattamente i campi che richiedi. Niente di più.
Questo conta di più sui client mobili dove la banda è limitata e la dimensione del payload influisce direttamente sulle prestazioni. Conta meno per la comunicazione server-server interna dove l’oggetto completo è spesso utile.
Risorse multiple in una richiesta
REST richiede tipicamente una richiesta HTTP per risorsa. Per recuperare un utente e i suoi ordini associati e i dettagli del prodotto di ogni ordine, si fanno tre richieste separate: una per l’utente, una per i suoi ordini, una per i prodotti. Ognuna è un round-trip.
GraphQL risolve i dati correlati in una singola richiesta. Una singola query può attraversare il grafo dei dati e restituire entità correlate profondamente annidate senza round-trip aggiuntivi.
Over-fetching e under-fetching
L’over-fetching è ricevere più dati del necessario. L’under-fetching è ricevere troppo poco, richiedendo richieste aggiuntive. Le API REST ottimizzate per un client tendono a fare over-fetch per un altro. Le app mobile spesso fanno under-fetch dagli endpoint progettati per i client web.
GraphQL elimina entrambi i problemi per design: il client specifica esattamente di cosa ha bisogno.
Il sistema di tipi
GraphQL ha uno schema obbligatorio fortemente tipizzato. Ogni tipo, campo, argomento e valore restituito è dichiarato. Lo schema è la fonte di verità e abilita l’analisi statica, la generazione di codice e un eccellente supporto IDE.
REST si affida a OpenAPI per la tipizzazione, che è opzionale. Molte API REST esistono senza alcuno schema formale, il che significa che i consumatori devono leggere la documentazione (se esiste) piuttosto che interrogare l’API direttamente.
Versioning
Le API REST sono tipicamente versioniate nell’URL: /v1/users, /v2/users. Questo è esplicito e facile da capire, ma crea versioni API parallele che devono essere mantenute contemporaneamente durante i periodi di deprecazione.
GraphQL depreca i campi nello schema usando la direttiva @deprecated piuttosto che creare nuove versioni URL. I client che usano campi deprecati continuano a funzionare; il tooling mostra l’avviso di deprecazione. Questo è più pulito in teoria, sebbene la gestione di uno schema grande con molti campi deprecati abbia la sua complessità.
HTTP Caching
REST si memorizza naturalmente nella cache a livello HTTP. Una risposta GET /api/users/123 può essere memorizzata nella cache da CDN, proxy e browser usando intestazioni di cache HTTP standard. Questo è uno dei vantaggi operativi più significativi di REST: ottieni infrastruttura di caching gratuitamente.
GraphQL usa POST per default (le query includono la stringa di query nel corpo), che non è nativamente memorizzabile nella cache a livello HTTP. Le query persistenti (dove il client invia un hash della query piuttosto che il testo completo della query, abilitando richieste GET per query memorizzabili nella cache) risolvono questo ma richiedono sforzo di implementazione aggiuntivo. Apollo e client simili supportano le query persistenti, ma non è automatico.
Esempio di codice: Gli stessi dati in REST vs GraphQL
Considera il recupero di un utente con i suoi ordini recenti. Ecco come ogni approccio lo gestisce.
REST: tre richieste
1GET /api/v1/users/123
2Authorization: Bearer <token>
3
4Response:
5{
6 "id": 123,
7 "name": "Sarah Clarke",
8 "email": "[email protected]",
9 "created_at": "2024-01-15",
10 "role": "customer",
11 "preferences": { ... }
12}
13
14GET /api/v1/users/123/orders?limit=5
15Response: [ { "id": 901, "total": 49.99, "status": "shipped", ... }, ... ]
16
17GET /api/v1/orders/901/items
18Response: [ { "product_id": 42, "name": "Widget Pro", "qty": 2 }, ... ]
GraphQL: una richiesta
1query UserWithOrders {
2 user(id: "123") {
3 name
4 email
5 orders(limit: 5) {
6 id
7 total
8 status
9 items {
10 productId
11 name
12 quantity
13 }
14 }
15 }
16}
La versione GraphQL restituisce esattamente i campi specificati (nessun created_at, nessun preferences, nessun role) e risolve tutte e tre le sorgenti dati in un unico round-trip HTTP. Per un client mobile su una connessione lenta, questo è un vantaggio significativo.
Realtà delle prestazioni: Cosa il marketing non dice
L’efficienza di recupero dati di GraphQL è reale, ma GraphQL in produzione ha un problema di prestazioni ben noto: il problema delle query N+1 nei resolver.
Quando un resolver GraphQL recupera un elenco di utenti e ogni utente ha un campo ordini, un’implementazione naïve eseguirà una query al database per recuperare N utenti, poi N query individuali per recuperare gli ordini di ogni utente. Per 100 utenti sono 101 query al database per quello che dovrebbero essere 2.
La soluzione è DataLoader, un’utilità di batching e caching che raggruppa le ricerche individuali in query batch. DataLoader non è opzionale per GraphQL in produzione; è un passaggio di implementazione obbligatorio. Ogni campo lista nel tuo schema che risolve dati correlati ha bisogno di DataLoader configurato correttamente, altrimenti il tuo database soffrirà sotto carico reale.
REST non ha questo problema. Ogni endpoint esegue le query di cui ha bisogno, tipicamente con un singolo JOIN o un piccolo numero di query coordinate progettate dallo sviluppatore che ha scritto l’endpoint.
L’altra considerazione sulle prestazioni è la complessità della query. GraphQL consente ai client di costruire query arbitrariamente profonde. Un client malintenzionato o mal progettato può inviare una query che attraversa relazioni profondamente annidate e innesca un enorme carico sul database. La limitazione della profondità della query e il punteggio della complessità della query sono misure di sicurezza e prestazioni obbligatorie per qualsiasi API GraphQL pubblica.
Considerazioni sulla sicurezza
REST ha un modello di sicurezza più semplice. Ogni endpoint è una superficie discreta che può avere il proprio middleware: controlli di autenticazione, regole di autorizzazione, rate limiting, validazione degli input. Uno stack di middleware a livello di rotta significa che la logica di sicurezza per POST /api/orders è autonoma e verificabile.
Il modello a endpoint singolo di GraphQL significa che tutti gli accessi fluiscono attraverso un unico punto. L’autorizzazione deve essere implementata a livello di resolver, ed è facile perderla. Se un tipo utente espone un campo adminNotes e il resolver non controlla il ruolo del chiamante, quel campo è accessibile a chiunque sappia come richiederlo. Le librerie di autorizzazione a livello di campo (come graphql-shield) esistono, ma richiedono un’implementazione deliberata piuttosto che essere la struttura naturale del codice.
L’abuso delle query è una preoccupazione significativa per le API GraphQL pubbliche. Senza la limitazione della profondità e il punteggio della complessità della query, una singola query malintenzionata può innescare un denial of service. Apollo Server e altri runtime forniscono questi controlli, ma devono essere configurati esplicitamente.
L’introspezione, ottima per il tooling degli sviluppatori in fase di sviluppo, dovrebbe essere disabilitata in produzione per le API pubbliche. Consente a chiunque di enumerare l’intero schema, che è un’informazione utile per un attaccante che mappa il tuo modello di dati.
REST vs GraphQL: Confronto fianco a fianco
| Criterio | REST | GraphQL |
|---|---|---|
| Controllo recupero dati | Definito dal server | Definito dal client |
| Risorse multiple | Più round-trip | Richiesta singola |
| Over-fetching | Comune | Eliminato |
| HTTP caching | Nativo (richieste GET) | Richiede query persistenti |
| Sistema di tipi | Opzionale (OpenAPI) | Obbligatorio |
| Versioning | Versioning URL | Deprecazione schema |
| Curva di apprendimento | Bassa | Da moderata ad alta |
| Problema N+1 | Non applicabile | Richiede DataLoader |
| Modello di sicurezza | Middleware per endpoint | Autorizzazione a livello resolver |
| Maturità del tooling | Molto maturo | Maturo |
| Usabilità API pubblica | Eccellente | Buona con documentazione |
Quando scegliere REST
REST è la scelta giusta nei seguenti scenari.
Operazioni CRUD semplici. Se la tua API è principalmente operazioni di creazione/lettura/aggiornamento/eliminazione su risorse discrete senza relazioni complesse, il modello orientato alle risorse di REST è un adattamento naturale. Il sovraccarico di uno schema GraphQL non è giustificato.
API pubbliche con consumatori esterni. Le API REST sono universalmente comprese. Qualsiasi sviluppatore, in qualsiasi linguaggio, può consumare un’API REST con un client HTTP di base. GraphQL richiede una libreria client GraphQL o la conoscenza della sintassi di query. Per le API consumate da sviluppatori terzi, la scopribilità e la semplicità di REST sono vantaggi materiali.
Quando il caching HTTP è importante. Se il caching CDN, il caching del browser o il caching edge fa parte della tua architettura di prestazioni, il caching nativo basato su GET di REST è un vantaggio significativo rispetto alla complessità aggiuntiva di GraphQL.
Team senza esperienza GraphQL. GraphQL ha una vera curva di apprendimento: progettazione dello schema, architettura del resolver, DataLoader, gestione della complessità delle query, query persistenti. Se il tuo team non ha esperienza con esso, il costo di produttività durante l’adozione è reale e non dovrebbe essere liquidato.
Microservizi che comunicano internamente. La comunicazione servizio-servizio all’interno di un sistema backend raramente beneficia delle query definite dal client di GraphQL. Ogni servizio tipicamente sa esattamente di cosa ha bisogno da un altro servizio, rendendo il modello a contratto fisso di REST più appropriato.
Quando scegliere GraphQL
GraphQL giustifica la sua complessità in circostanze specifiche.
Grafi di dati complessi con molte relazioni. Reti sociali, cataloghi di prodotti con gerarchie di attributi profondi, sistemi di gestione dei contenuti con modelli di relazione complessi: questi sono gli spazi problematici per cui GraphQL è stato progettato. Quando i tuoi dati assomigliano più a un grafo che a una tabella, il modello di query di GraphQL è un adattamento naturale.
Client mobili dove la banda conta. Recuperare solo i campi di cui uno schermo ha bisogno, combinare più query correlate in una richiesta, ed evitare l’over-fetching sono tutti significativi su mobile. Facebook ha costruito GraphQL specificamente perché la loro app mobile stava soffrendo sotto il sovraccarico di trasferimento dati di REST.
Consumatori multipli con esigenze di dati diverse. Un’app web, un’app mobile e un’integrazione di terze parti potrebbero tutte aver bisogno di sottoinsiemi diversi degli stessi dati sottostanti. Con REST o costruisci più endpoint o restituisci un sovrainsieme e lasci che ogni client ignori ciò di cui non ha bisogno. Con GraphQL ogni client richiede esattamente ciò che mostra.
Iterazione frontend rapida. Quando il team frontend ha bisogno di aggiungere un campo a una schermata e il team backend dovrebbe altrimenti aggiornare un endpoint REST per includerlo, GraphQL elimina quel costo di coordinazione. Il campo deve solo esistere nello schema (ed essere risolvibile); il team frontend può aggiungerlo alla propria query senza una modifica backend.
API interne dove controlli entrambe le estremità. I vantaggi del tooling di GraphQL, inclusa la generazione di codice, la type safety e l’introspezione dello schema, forniscono il maggior valore quando sia il client che il server sono costruiti e mantenuti dallo stesso team.
La raccomandazione onesta per il 2026
La maggior parte dei team software che costruiscono nuovi progetti nel 2026 sarà meglio servita da REST. Non è un rifiuto di GraphQL; è il riconoscimento che i costi di GraphQL sono reali e i suoi vantaggi sono convincenti solo in circostanze specifiche.
La curva di apprendimento di GraphQL è più ripida di quanto i suoi sostenitori spesso riconoscano. La progettazione dello schema è una competenza. I pattern DataLoader richiedono comprensione. L’autorizzazione a livello di campo richiede un’architettura deliberata. La gestione della complessità delle query è facile da trascurare. Nessuno di questi è insormontabile, ma si sommano a un investimento significativo durante la build iniziale, e devono essere mantenuti correttamente man mano che lo schema cresce.
I vantaggi di caching di REST sono sottostimati nella maggior parte dei confronti. La capacità di mettere un CDN davanti alla tua API e memorizzare nella cache le risposte GET aggressivamente è genuinamente potente. Molte applicazioni ad alto traffico servono la maggior parte del loro traffico dalla cache, e REST lo rende semplice. GraphQL lo rende possibile con le query persistenti, ma richiede lavoro aggiuntivo.
Scegli GraphQL quando i tuoi dati sono genuinamente a forma di grafo, quando hai più client con esigenze di dati divergenti, o quando il tuo team frontend ha bisogno della flessibilità di far evolvere le proprie query senza modifiche backend. Scegli REST quando stai costruendo un’API pubblica, quando il tuo team non ha esperienza GraphQL, o quando il caching HTTP è importante per la tua architettura.
Il peggior risultato è scegliere GraphQL perché sembra più moderno e poi passare il primo mese del progetto a costruire infrastrutture che REST avrebbe dato gratuitamente.
Punti chiave
- REST è il default pragmatico per la maggior parte dei progetti: complessità minore, caching HTTP nativo e compatibilità client universale
- I veri vantaggi di GraphQL sono l’eliminazione dell’over-fetching, le query multi-risorsa in una sola richiesta e le forme di dati definite dal client; questi contano di più per i client mobili e i modelli di dati complessi
- Il problema N+1 nei resolver GraphQL è una realtà di produzione, non una preoccupazione teorica; DataLoader è obbligatorio, non opzionale
- Il modello di sicurezza per endpoint di REST è più semplice da ragionare rispetto all’autorizzazione a livello resolver di GraphQL; questo conta per i team senza esperienza GraphQL
- GraphQL aggiunge il massimo valore quando controlli sia il client che il server e le relazioni tra i dati sono genuinamente complesse
- Scegli REST per API pubbliche, CRUD semplice e architetture con caching pesante; scegli GraphQL per API interne complesse con più consumatori frontend
Domande frequenti
GraphQL sta sostituendo REST? No. L’adozione di GraphQL è cresciuta costantemente ma REST rimane dominante per le nuove API nel 2026. Entrambe le tecnologie sono attivamente sviluppate e hanno entrambe casi d’uso forti. GraphQL non ha reso REST obsoleto; ha occupato una nicchia per tipi di problemi specifici.
GraphQL e REST possono coesistere nello stesso progetto? Sì, ed è comune. Un’API REST pubblica per i consumatori di terze parti accanto a un’API GraphQL interna per i prodotti frontend dell’azienda è un’architettura sensata. I due approcci servono esigenze diverse e possono condividere lo stesso layer di dati sottostante.
GraphQL è più difficile da imparare di REST? Sì, significativamente. I concetti di REST si mappano direttamente su HTTP, che la maggior parte degli sviluppatori già comprende. GraphQL richiede di imparare il linguaggio di query, il linguaggio di definizione dello schema, l’architettura del resolver, i pattern DataLoader e un insieme separato di controlli di sicurezza. Aspettati qualche settimana perché un team diventi produttivo, non qualche giorno.
GraphQL ha prestazioni migliori di REST? Dipende dal carico di lavoro. GraphQL può ridurre il numero di round-trip HTTP, il che aiuta sulle connessioni ad alta latenza. Ma non si memorizza nella cache così naturalmente come REST, e un server GraphQL mal implementato con resolver non ottimizzati funzionerà peggio di un’API REST equivalente. Le prestazioni dipendono fortemente dalla qualità dell’implementazione.
Cos’è il problema N+1 in GraphQL? Quando un resolver GraphQL recupera un elenco e ogni elemento nell’elenco innesca una query individuale per dati correlati, si ottengono N+1 query al database invece delle 2 attese. Un elenco di 100 utenti dove ogni utente risolve i propri ordini individualmente esegue 101 query. DataLoader risolve questo raggruppando le ricerche individuali in una singola query per batch.
Quale dovrei usare per una nuova API startup nel 2026? REST, a meno che tu non abbia ragioni specifiche per non farlo. Inizia con REST, documentalo con OpenAPI, e costruisci su di esso finché non hai prove concrete che i punti di forza di GraphQL si applicano al tuo problema. Migrare da REST a GraphQL è possibile; iniziare con GraphQL e scoprire che non ne avevi bisogno significa portare complessità non necessaria per tutta la vita del progetto.
Commenti