Che cos'è GraphQL?

Aggiornato: ottobre 2026

GraphQL è un linguaggio di query per le API e un runtime lato server che restituisce esattamente i campi richiesti da ogni client in una sola richiesta. La dualità conta: il linguaggio è una specifica che qualsiasi client può parlare; il runtime esegue quelle query contro un sistema di tipi definito sopra i dati già esistenti – qualsiasi database, qualsiasi servizio. Non è un database, e non sostituisce né l’archiviazione né, necessariamente, l’API REST.

Punti chiave

DomandaRisposta
Che cos’èUn linguaggio di query regolato da una spec + un runtime di esecuzione – agnostico rispetto all’archiviazione
La mossa caratteristicaLa forma della risposta rispecchia quella della query: si chiedono dei campi, si ottengono quei campi
Le tre operazioniquery (lettura) · mutation (scrittura) · subscription (push in tempo reale)
I mattoniSchema (contratto SDL) · tipi · resolver (funzioni di recupero per campo)
La fattura onestaStrategia di cache, batching dell’N+1, limiti basati sul costo, rafforzamento della sicurezza

La demo caratteristica: query e risposta

La demo verso cui converge ogni spiegazione, perché è l’idea – la risposta è la query, compilata:

# Richiesta                            # Risposta
{                                      {
  post(id: "8fk2") {                     "data": {
    title                                  "post": {
    author {                                 "title": "Hello GraphQL",
      username                               "author": {
    }                                          "username": "ada"
    comments(first: 2) {                     },
      text                                   "comments": [
    }                                          { "text": "Nice." },
  }                                            { "text": "Ship it." }
}                                            ]
                                           }
                                         }
                                       }

Una sola richiesta, tre risorse collegate, zero campi non richiesti – la coppia overfetching e underfetching mandata in pensione in un colpo solo. Chiamarla da client reali è HTTP ordinario:

// JavaScript / Node.js — query Back4app's auto-generated GraphQL API
const res = await fetch('https://parseapi.back4app.com/graphql', {
  method: 'POST',
  headers: {
    'X-Parse-Application-Id': APP_ID,
    'X-Parse-Client-Key': CLIENT_KEY,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    query: '{ posts(first: 20) { edges { node { title author { username } } } } }',
  }),
});
const { data } = await res.json(); // shaped exactly like the query

Schema, query, resolver: il trio che fa il lavoro

Le spiegazioni mostrano la query; quasi nessuna mostra il meccanismo che le sta dietro come un quadro coerente. Lo schema è il contratto tipizzato, scritto in SDL:

type Post {
  title: String!          # ! = non nullo
  author: User!
  comments(first: Int): [Comment!]
}

type Query {              # i punti di ingresso in lettura
  post(id: ID!): Post
}

type Mutation {           # i punti di ingresso in scrittura
  createPost(title: String!): Post!
}

I resolver sono l’altra metà del runtime – una funzione per campo, ognuna libera di recuperare i dati da qualsiasi parte:

const resolvers = {
  Query: {
    post: (_, { id }) => db.posts.findById(id),
  },
  Post: {
    author: (post) => db.users.findById(post.authorId),   // chiamata per ogni post!
  },
};

L’esecuzione è una pipeline: analizzare la query, validarla contro lo schema (le operazioni non valide muoiono prima di toccare i dati), poi percorrere il selection set chiamando i resolver e assemblare il JSON speculare. Quella chiamata di resolver per ogni campo è anche il cartellino del prezzo della flessibilità – si noti il // chiamata per ogni post!, che più sotto diventa il problema N+1. Il nome, che nessuno spiega: i dati formano un grafo di oggetti tipizzati, e le query lo attraversano partendo dai campi radice – ma solo lungo i percorsi esposti dallo schema, non con attraversamenti arbitrari come in un vero linguaggio di query su grafi.

Provenienza, in breve: creato in Facebook (oggi Meta) nel 2012 per le sue app mobile, rilasciato open source nel 2015, governato dal 2018 dalla GraphQL Foundation sotto la Linux Foundation, edizione attuale della spec di ottobre 2021, con una bozza GraphQL over HTTP che standardizza le convenzioni di trasporto.

Query, mutation, subscription

Pipeline di esecuzione di GraphQLUn'operazione del client — query, mutation o subscription — arriva a un endpoint unico, viene analizzata e validata contro lo schema, eseguita chiamando un resolver per ogni campo richiesto su database o servizi, e restituita come JSON che rispecchia la forma della richiesta.

Operazione del client
query · mutation · subscription

Endpoint unico
/graphql

Analisi + validazione
contro lo schema

Esecuzione:
un resolver per campo

Database,
API, servizi

JSON che rispecchia
la forma della query

Un'operazione del client — query, mutation o subscription — arriva a un endpoint unico, viene analizzata e validata contro lo schema, eseguita chiamando un resolver per ogni campo richiesto su database o servizi, e restituita come JSON che rispecchia la forma della richiesta.

Le query leggono. Le mutation scrivono – e selezionano campi sul risultato, così il client riceve lo stato post-scrittura nello stesso giro di andata e ritorno. Le subscription tengono aperta una connessione (in pratica WebSocket) e spingono gli eventi appena si verificano; sono il capitolo tempo reale di GraphQL, con l’avvertenza che ogni subscription attiva è stato tenuto dal server. Tutte e tre condividono lo schema, il sistema di tipi e gli strumenti – un contratto, tre tempi verbali.

GraphQL vs. REST

CriterionGraphQLREST
EndpointUno solo (/graphql)Uno per risorsa
Forma della rispostaComposta dal client a ogni queryFissa per endpoint
Over/underfetchingRisolti a livello HTTPMitigati con parametri
Cache HTTPPersa per impostazione predefinita (un solo POST)Nativa – il superpotere
Tipizzazione e ispezioneIntegrate nel contrattoFacoltative via OpenAPI
VersionamentoEvoluzione senza versioni + @deprecatedConvenzioni /v1, /v2
Tempo realeSubscription nella specFuori perimetro
Punto di forzaClient eterogenei, dati annidatiCRUD su risorse, letture cacheabili

L’argomento completo – incluso quando REST è semplicemente la scelta migliore – vive nella voce dedicata GraphQL vs. API REST.

GraphQL in produzione: i costi onesti

La sezione che le spiegazioni commerciali addolciscono. Cache: un solo endpoint POST rinuncia alla cache HTTP e CDN indicizzata per URL; il rimpiazzo sono cache normalizzate lato client indicizzate su id più __typename, e le persisted query (operazioni pre-approvate e sottoposte ad hash, inviate come GET) per recuperare una parte della cache di trasporto. N+1: resolver ingenui trasformano una lista di 20 post in 1 + 20 letture sul database – lo stesso problema che i client REST hanno su HTTP, trasferito nel livello dei resolver e corretto lì con loader di batching come DataLoader. Errori: GraphQL restituisce 200 OK con un array errors – il monitoring basato sui codici di stato diventa cieco se non viene rieducato. Rate limiting: le richieste non si equivalgono quando una sola può annidare dieci relazioni; le API mature misurano il costo della query (analisi di profondità e complessità), non il numero di richieste. Sicurezza: conviene disattivare l’ispezione in produzione, imporre limiti di profondità e complessità e tenere l’autorizzazione nel livello di business sotto i resolver – l’endpoint unico accieca anche le regole WAF basate sull’URL, quindi la validazione si sposta dentro il livello GraphQL stesso.

Casi d’uso tipici

  • App mobile su reti limitate – il caso d’uso fondativo: campi esatti, byte minimi, meno andate e ritorni.
  • Prodotti multi-client – app per orologio, app per telefono, dashboard web, ognuna che modella le proprie risposte contro un unico schema.
  • Aggregazione backend-for-frontend – un livello GraphQL che compone diversi servizi interni per il consumo da parte delle UI.
  • Frontend che evolvono rapidamente – schermate nuove selezionano campi nuovi senza attendere endpoint nuovi.
  • Contratti tipizzati da un capo all’altro – l’ispezione dello schema genera client tipizzati, tenendo API e UI onesti già in compilazione.

Conviene usare GraphQL? Matrice decisionale

GraphQL si guadagna il suo meccanismo quando…Conviene REST quando…
I client hanno bisogno di dati diversi fra loroUn solo tipo di client, schermate stabili
Le schermate leggono dati annidati e relazionaliLe risorse si mappano in modo pulito sugli endpoint
Si aggregano più sorgenti di backendUn solo servizio è proprietario dei dati
La banda è preziosa (mobile-first)La cache HTTP/CDN può reggere il carico di lettura
Una piattaforma genera lo schema al posto del teamIl team deve costruire e irrobustire tutto a mano

Limiti e trade-off

  • La flessibilità la paga il server. Query arbitrarie dal client impongono che il server sia sicuro sotto qualsiasi forma – batching, limiti di costo e guardrail di profondità sono prerequisiti, non rifiniture.
  • La cache diventa un progetto a sé. Quello che HTTP regalava a REST, i team GraphQL lo reimplementano in cache lato client e persisted query.
  • L’osservabilità va reimparata. Un solo endpoint, risposte sempre a 200 e tempi per campo richiedono strumenti che capiscano GraphQL.
  • Upload di file e dati binari sono scomodi – di solito delegati a endpoint di upload separati, accanto al grafo.
  • La governance dello schema è organizzativa. Un contratto condiviso fra team ha bisogno di regole di proprietà; la federazione (comporre subgraph posseduti dai singoli team in un supergraph) è la risposta alla scala, e una disciplina a sé.

GraphQL 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. La parte distintiva è da dove arriva lo schema: si definisce un modello di dati e la piattaforma genera l’API GraphQL – tipi di oggetto tipizzati, campi di query e mutation, connection che attraversano le relazioni come nell’esempio posts → author qui sopra – senza resolver da scrivere, perché Back4app li implementa contro il database con i permessi applicati a ogni richiesta. Le schede di codice mostrano tutta la storia lato client: un POST verso /graphql con le chiavi dell’app. Una console GraphQL integrata copre l’esplorazione, REST resta disponibile sugli stessi dati per letture compatibili con la cache, e la logica su misura entra nello schema sotto forma di funzioni Cloud Code – la sezione dei costi onesti qui sopra diventa in gran parte la fattura della piattaforma, non quella di chi sviluppa.

Domande frequenti

Che cos'è GraphQL in parole semplici?

Un linguaggio di query che permette a un client di chiedere a un'API esattamente i campi che gli servono – relazioni annidate comprese – in una sola richiesta, più un runtime lato server che soddisfa quelle richieste a partire dalle sorgenti di dati già esistenti. Si mette davanti a qualsiasi database o servizio; non è un database.

GraphQL è meglio di REST?

Nessuno dei due è universalmente migliore. GraphQL vince con client eterogenei, vincoli di banda e dati aggregati da più sorgenti; REST vince sulla cache HTTP, sulla semplicità e sulla maturità degli strumenti per il CRUD a forma di risorse. Il pattern dominante in produzione è pragmatico: un livello GraphQL per i frontend sopra interni REST o RPC.

GraphQL è un database o qualcosa come SQL?

No – è un linguaggio di API a livello applicativo, agnostico rispetto all'archiviazione per progetto: i resolver possono leggere da qualsiasi database, da un'altra API o da un file. E malgrado il nome, non è un linguaggio generale di query su grafi come SPARQL; il grafo si attraversa solo lungo i percorsi che lo schema espone.

Che cosa sono query, mutation e subscription?

I tre tipi di operazione. Le query leggono i dati; le mutation li scrivono – e restituiscono il nuovo stato nello stesso giro di andata e ritorno, così il client si aggiorna senza una lettura successiva; le subscription spingono aggiornamenti in tempo reale su una connessione persistente, tipicamente WebSocket. Tutte e tre sono validate contro lo stesso schema.

Che cos'è uno schema GraphQL?

Il contratto tipizzato fra client e server, scritto nello Schema Definition Language: i tipi di oggetto, i loro campi e i punti di ingresso radice Query, Mutation e Subscription. Ogni operazione in arrivo è validata contro di esso prima dell'esecuzione, e gli strumenti lo ispezionano per generare documentazione e client tipizzati.

Che cos'è un resolver?

Una funzione lato server che recupera il valore di un singolo campo – da un database, da un'altra API o da qualsiasi altra parte. Il runtime percorre ogni query e chiama il resolver di ogni campo richiesto: è al tempo stesso la flessibilità di GraphQL e l'origine del suo problema N+1, quando i resolver degli elementi di una lista interrogano ciascuno separatamente.

GraphQL funziona solo su HTTP POST?

Per specifica GraphQL è agnostico rispetto al trasporto; in pratica viene servito su un singolo endpoint HTTP – per convenzione /graphql – di solito via POST con un corpo JSON, con GET ammesso per le query e WebSocket a trasportare le subscription. Una specifica GraphQL over HTTP standardizza oggi queste convenzioni.

Quando conviene NON usare GraphQL?

CRUD semplice su risorse con client uniformi, traffico di lettura che la cache HTTP e CDN potrebbe assorbire, trasferimenti pesanti di file e team piccoli senza voglia di occuparsi di batching dei resolver, limiti basati sul costo delle query e governance dello schema. In questi casi un'API REST ben progettata è meno meccanismo per lo stesso risultato.

Termini correlati

Confronta con

Fonti di approfondimento

Pronto a costruire il tuo backend?

Avvia il tuo progetto su Back4app in pochi minuti: database, autenticazione, API e Cloud Code inclusi. Nessuna carta di credito richiesta.

Scritto e revisionato da Back4app Engineering, Back4app Engineering · Pubblicato il 2026-10-05