REST è uno stile di API con molti endpoint fissi; GraphQL è un linguaggio di query in cui il client chiede a un solo endpoint i campi che gli servono. Il confronto riguarda in realtà chi decide la forma della risposta: in REST l’ha decisa il server in fase di progettazione; in GraphQL la decide il client a ogni richiesta. Tutto il resto – cache, versionamento, errori, prestazioni – discende da quella singola inversione.
Punti chiave
| Domanda | Risposta |
|---|---|
| REST | Molti endpoint, risposte definite dal server, cache nativa di HTTP |
| GraphQL | Un endpoint, schema tipizzato, campi e annidamento scelti dal client |
| La vittoria di GraphQL | Overfetching e underfetching muoiono; un round trip per schermata |
| La vittoria di REST | Cache CDN, semplicità, supporto universale |
| La realtà del 2026 | Coesistenza – REST da ogni parte, GraphQL come livello di aggregazione del frontend |
La stessa schermata, nei due modi
Una schermata di profilo ha bisogno di un utente, dei suoi cinque post più recenti e del numero di follower. REST parla per risorse:
GET /users/42 → 38 campi, ne servivano 3 (overfetching)
GET /users/42/posts?limit=5 → secondo round trip (underfetching)
GET /users/42/followers → terzo round trip
GraphQL parla con una sola domanda modellata:
POST /graphql
query {
user(id: 42) {
name
avatarUrl
posts(first: 5) { title likes }
followers { totalCount }
}
}
→ un solo round trip, esattamente quei campi, nient'altro
Il divario si restringe più di quanto suggeriscano i titoloni: anche un REST ben progettato supporta la selezione dei campi – e i query builder degli SDK la rendono un’abitudine di prima classe:
// JavaScript / Node.js — Back4app JS SDK
// GraphQL's best trick — ask only for what you need — without leaving REST
const query = new Parse.Query('Article');
query.equalTo('status', 'published');
query.select('title', 'views'); // field selection, GraphQL-style
const articles = await query.find(); // lean payload over the REST API
// The same backend also speaks real GraphQL: query { articles { ... } } // Flutter / Dart — Back4app Flutter SDK
// GraphQL's best trick — ask only for what you need — without leaving REST
final query = QueryBuilder<ParseObject>(ParseObject('Article'))
..whereEqualTo('status', 'published')
..keysToReturn(['title', 'views']); // field selection, GraphQL-style
final response = await query.query(); // lean payload over the REST API // iOS / Swift — Back4app Swift SDK
// GraphQL's best trick — ask only for what you need — without leaving REST
let query = Article.query("status" == "published")
.select("title", "views") // field selection, GraphQL-style
query.find { result in
if case .success(let articles) = result { render(articles) }
} // Android / Kotlin — Back4app Android SDK
// GraphQL's best trick — ask only for what you need — without leaving REST
val query = ParseQuery.getQuery<ParseObject>("Article")
query.whereEqualTo("status", "published")
query.selectKeys(listOf("title", "views")) // field selection, GraphQL-style
query.findInBackground { articles, e -> if (e == null) render(articles) } GraphQL vs. REST a colpo d’occhio
| Dimensione | REST | GraphQL |
|---|---|---|
| Endpoint | Molti, a forma di risorse | Uno solo, a forma di schema |
| Forma della risposta | Definita dal server | Scelta dal client a ogni query |
| Tipizzazione | Convenzione (OpenAPI facoltativo) | Garantita dallo schema, ispezionabile |
| Andate e ritorni | Uno per risorsa | Uno per schermata |
| Cache | Nativa HTTP/CDN, indicizzata per URL | Normalizzata lato client; persisted query |
| Versionamento | /v1 → /v2 | Evolvere + deprecare, senza versioni |
| Errori | Codici di stato HTTP | 200 + array errors, risultati parziali |
| Tempo reale | A parte (webhook, socket) | Subscription nella spec |
| Curva di apprendimento | Minima | Schema, resolver, controllo dei costi |
| Primo abbinamento ideale | CRUD pubblico, cacheabile, semplice | Frontend multi-client, densi di dati |
Le parti che le pagine di confronto saltano
Il problema N+1 ha cambiato indirizzo, non è morto. Una query GraphQL per post-con-autori fa scattare ingenuamente una chiamata di resolver per ogni post – la stessa patologia N+1 che gli ORM hanno reso celebre, ora lato server. La cura standard è il batching: un loader per richiesta raccoglie gli identificatori degli autori e li recupera con una sola query. Adottare GraphQL senza una strategia di batching significa adottare il peggior bug prestazionale di REST a un nuovo indirizzo.
Gli errori sono una decisione operativa. “200 con un array errors” significa che dashboard, alerting e logica CDN costruiti sui codici di stato diventano ciechi per impostazione predefinita. I team che prosperano con GraphQL trattano l’osservabilità degli errori come parte dell’adozione, non come un’aggiunta a posteriori.
Le query senza limiti hanno bisogno di limiti. Un solo endpoint flessibile significa che una singola query può attraversare l’intero grafo – le indicazioni ufficiali di sicurezza parlano di limiti di profondità, budget sul costo delle query e allowlist di persisted query per i client interni. Gli endpoint fissi di REST rendevano implicito il controllo dei costi; GraphQL lo lascia in mano a chi sviluppa.
Casi d’uso tipici
- GraphQL: app mobile su reti lente, dashboard che cuciono insieme molte entità, prodotti con client web + mobile + partner dai bisogni di dati divergenti, iterazione rapida del frontend contro uno schema stabile.
- REST: API pubbliche per sviluppatori, distribuzione di contenuti cacheabili, superfici di webhook e integrazione, trasferimento di file, chiamate fra servizi dove vince la semplicità.
- Entrambi (la norma enterprise): REST o RPC fra i servizi di backend; un livello GraphQL che li aggrega per i frontend – il pattern backend-for-frontend con uno schema.
Conviene scegliere GraphQL o REST? Matrice decisionale
| Scegliere REST quando… | Scegliere GraphQL quando… | Usare entrambi quando… |
|---|---|---|
| L’API è consumata da parti terze | Le schermate cuciono molte risorse | I servizi parlano REST, i frontend vogliono forme |
| La cache CDN regge il carico | I client hanno bisogni di dati diversi | Un’API pubblica e un frontend di prodotto convivono |
| Le risorse si mappano 1:1 sulle schermate | L’overfetching fa soffrire gli utenti mobile | Si migra in modo incrementale |
| Il team rilascia questa settimana | I contratti tipizzati accelerano il lavoro frontend | Team diversi sono proprietari di livelli diversi |
| Dominano file e webhook | Le subscription in tempo reale sono centrali | Meglio non riaprire il dibattito |
Il punto di partenza onesto: conviene iniziare con REST e aggiungere GraphQL quando il dolore della modellazione dei dati per client eterogenei arriva davvero – e se la piattaforma genera entrambi da un solo schema, la scelta smette di essere architetturale e diventa una decisione per singola richiesta.
Limiti e trade-off
- REST: over/underfetching sulle schermate dense di dati, migrazioni di versione, deriva della forma delle risposte fra i team e N endpoint di documentazione.
- GraphQL: la cache richiede meccanismi, il controllo dei costi richiede vigilanza, i resolver richiedono disciplina di batching e il pattern 200-con-errors richiede di rifare l’osservabilità.
- Entrambi: nessuno dei due ripara un modello di dati sbagliato – un dominio confuso produce un’API confusa in qualunque stile, come la tesi stessa su REST lascia intendere con discrezione: i vincoli hanno sempre riguardato l’architettura sottostante.
GraphQL e REST su Back4app
Back4app è una piattaforma open-source di Backend as a Service (BaaS) che combina database gestito, API REST e GraphQL generate automaticamente, autenticazione, archiviazione di file e funzioni serverless con Cloud Code. Il dilemma di questo articolo si dissolve alla radice: entrambi gli stili di API sono generati dallo stesso schema – endpoint REST cacheabili per URL e un’API GraphQL tipizzata con query annidate – più gli SDK la cui selezione dei campi (le schede di codice qui sopra) consegna il beneficio di punta di GraphQL su entrambi i trasporti. Si sceglie per client, si cambia per schermata, e il livello di API non va scritto affatto.
Domande frequenti
Qual è la differenza principale fra GraphQL e REST?
La forma del contratto. REST espone molti endpoint di risorse, ognuno dei quali restituisce una risposta definita dal server – si prende quello che l'endpoint dà. GraphQL espone un solo endpoint con uno schema tipizzato, e ogni client scrive una query che nomina esattamente i campi e le relazioni annidate che vuole. REST fissa le risposte sul server; GraphQL sposta quella decisione sul client.
GraphQL è più veloce di REST?
Per le schermate che hanno bisogno di dati da più risorse, di solito sì – una query sostituisce diverse andate e ritorni e il payload porta solo i campi richiesti. Per una singola risorsa semplice REST è spesso più rapido, perché le sue risposte indicizzate per URL si mettono in cache magnificamente sui CDN. E resolver scritti male possono rendere GraphQL più lento di qualsiasi alternativa, per via del problema N+1. Decide il carico di lavoro.
Che cosa sono overfetching e underfetching?
I due punti dolenti di REST per cui GraphQL è stato costruito. Overfetching: un endpoint restituisce l'intera risorsa quando alla schermata servono tre campi. Underfetching: una chiamata non basta, così il client ne fa altre N per i dati collegati. La selezione dei campi e le query annidate affrontano entrambi i problemi – ed è per questo che le app multi-client e dense di dati sono le prime a sentire l'attrazione verso GraphQL.
GraphQL sta sostituendo REST?
No – i dati del settore parlano di coesistenza. I sondaggi mostrano con costanza che la grande maggioranza dei team usa REST, con circa un terzo che adotta GraphQL, nella maggior parte dei casi accanto a REST e non al suo posto. Il pattern enterprise dominante è ibrido: REST (o RPC) fra i servizi e per le API pubbliche, con GraphQL come livello di aggregazione al servizio dei client frontend.
In che modo la cache è diversa fra REST e GraphQL?
Le risposte REST vivono a URL univoci, quindi browser e CDN le mettono in cache a costo zero – il suo superpotere silenzioso. GraphQL invia tipicamente delle POST a un solo endpoint, e questo rompe la cache indicizzata per URL; l'ecosistema compensa con cache normalizzate lato client e persisted query su GET. La cache è l'argomento più forte in favore di REST sulle API pubbliche a forte traffico di lettura.
In che modo il versionamento è diverso?
REST versiona in modo esplicito – una v2 nell'URL o in un header – e tiene in piedi entrambe le versioni durante le migrazioni. GraphQL punta all'evoluzione senza versioni: si aggiungono campi nuovi liberamente, si marcano quelli vecchi come deprecati, si osserva la telemetria di utilizzo e si rimuovono quando i client smettono di chiederli. Funzionano entrambi; GraphQL scambia la cerimonia delle versioni con la disciplina della governance dello schema.
In che modo gli errori sono diversi fra i due?
REST si appoggia ai codici di stato HTTP – un 404 è visibile a ogni proxy, strumento di monitoring e libreria client. GraphQL restituisce di solito un 200 con un array errors accanto a dati parziali: questo abilita il successo parziale, ma impone al monitoring di analizzare i corpi delle risposte invece di fidarsi dei codici di stato. È una differenza operativa reale, non una nota a piè di pagina.
Quando conviene ancora scegliere REST?
Segnali concreti: API pubbliche consumate da molte parti terze, traffico di lettura fortemente cacheabile, CRUD semplice a forma di risorse, upload e download di file, integrazioni in stile webhook e team senza esperienza operativa di GraphQL. REST è l'opzione predefinita che tutto supporta; GraphQL è lo specialista che si ingaggia per frontend multi-client e densi di dati.