Che cos'è GraphQL? Guida chiara per API e recupero dati
Scopri cos'è GraphQL, come funzionano query, mutation e schema, e quando usarlo invece di REST—più vantaggi, svantaggi e esempi pratici.

Che cos'è GraphQL (e cosa non è)
GraphQL è un linguaggio di query e un runtime per API. In poche parole: è un modo per un'app (web, mobile o un altro servizio) di chiedere a un'API dei dati con una richiesta chiara e strutturata — e per il server di restituire una risposta che corrisponde a quella richiesta.
Il problema che risolve
Molte API costringono i client ad accettare tutto ciò che un endpoint fisso restituisce. Questo porta spesso a due problemi:
- Over-fetching: scaricare campi che non usi.
- Under-fetching: fare più richieste per assemblare una schermata.
Con GraphQL, il client può richiedere esattamente i campi di cui ha bisogno, né più né meno. Questo è particolarmente utile quando schermate diverse (o app diverse) necessitano di "fette" diverse dello stesso dato sottostante.
Dove “vive” GraphQL
GraphQL di solito sta tra le app client e le tue sorgenti di dati. Quelle sorgenti possono essere:
- database
- servizi REST esistenti
- API di terze parti
- microservizi
Il server GraphQL riceve una query, decide come recuperare ogni campo richiesto dal posto giusto e poi compone la risposta JSON finale.
Un modello mentale veloce
Pensa a GraphQL come ordinare una risposta su misura:
- Il client descrive la forma dei dati che vuole.
- Il server restituisce i dati in quella stessa forma (quando possibile).
Cosa GraphQL non è
GraphQL viene spesso frainteso, quindi ecco alcune chiarificazioni:
- Non è un database (non conserva i tuoi dati).
- Non è automaticamente più veloce (può ridurre il trasferimento di dati non necessari, ma il lavoro sul server conta ancora).
- Non è "REST 2.0" (è un approccio alternativo alle API con punti di forza e compromessi diversi).
Se mantieni questa definizione centrale — linguaggio di query + runtime per API — avrai la base giusta per tutto il resto.
Perché è stato creato GraphQL
GraphQL è nato per risolvere un problema pratico di prodotto: i team passavano troppo tempo ad adattare le API alle schermate reali.
Le API tradizionali basate su endpoint spesso costringono a scegliere tra spedire più dati del necessario o effettuare chiamate extra per ottenere ciò che serve. Con la crescita del prodotto, questa frizione si traduce in pagine più lente, codice client più complesso e coordinazione difficile tra frontend e backend.
I punti dolenti su cui punta GraphQL
Over-fetching accade quando un endpoint restituisce un oggetto “completo” anche se una schermata ha bisogno solo di pochi campi. Una vista profilo mobile potrebbe aver bisogno solo di nome e avatar, ma l'API restituisce indirizzi, preferenze, campi di audit e altro ancora. Questo spreca banda e può penalizzare l'esperienza utente.
Under-fetching è l'opposto: nessun endpoint singolo ha tutto ciò che serve, quindi il client deve fare più richieste e unire i risultati. Questo aumenta la latenza e il rischio di errori parziali.
Far evolvere le API senza continue versioni
Molte API in stile REST rispondono al cambiamento aggiungendo nuovi endpoint o versionando (v1, v2, v3). Il versioning può essere necessario, ma crea lavoro di manutenzione a lungo termine: i client vecchi continuano a usare vecchie versioni mentre nuove funzionalità si accumulano altrove.
L'approccio di GraphQL è far evolvere lo schema aggiungendo campi e tipi nel tempo, mantenendo stabili i campi esistenti. Questo spesso riduce la pressione di creare “nuove versioni” solo per supportare nuove necessità dell'interfaccia.
Una API, molti client
I prodotti moderni raramente hanno un solo consumatore. Web, iOS, Android e integrazioni partner richiedono tutte forme di dati diverse.
GraphQL è progettato in modo che ogni client possa richiedere esattamente i campi di cui ha bisogno — senza che il backend debba creare un endpoint separato per ogni schermata o dispositivo.
Lo schema GraphQL: il contratto dell'API
Un'API GraphQL è definita dal suo schema. Pensalo come l'accordo tra server e client: elenca quali dati esistono, come sono connessi e cosa può essere richiesto o modificato. I client non indovinano endpoint: leggono lo schema e chiedono campi specifici.
Basi dello schema: tipi, campi, relazioni
Lo schema è composto da tipi (come User o Post) e campi (come name o title). I campi possono puntare ad altri tipi, ed è così che GraphQL modella le relazioni.
Ecco un esempio semplice in Schema Definition Language (SDL):
type User {
id: ID!
name: String!
posts: [Post!]!
}
type Post {
id: ID!
title: String!
body: String
author: User!
comments: [Comment!]!
}
type Comment {
id: ID!
text: String!
author: User!
post: Post!
}
Tipizzazione forte = validazione prima dell'esecuzione
Poiché lo schema è fortemente tipizzato, GraphQL può validare una richiesta prima di eseguirla. Se un client chiede un campo che non esiste (per esempio, Post.publishDate quando lo schema non prevede quel campo), il server può rifiutare o soddisfare parzialmente la richiesta con errori chiari — senza comportamenti ambigui.
Evolvere in sicurezza nel tempo
Gli schemi sono pensati per crescere. Di solito puoi aggiungere nuovi campi (per esempio User.bio) senza rompere i client esistenti, perché i client ricevono solo ciò che chiedono. Rimuovere o cambiare campi è più delicato, perciò i team spesso deprecano i campi prima di eliminarli e migrano i client gradualmente.
Query: chiedere esattamente ciò che serve
Un'API GraphQL è tipicamente esposta tramite un endpoint singolo (per esempio, /graphql). Invece di avere molte URL per risorse diverse (come /users, /users/123, /users/123/posts), mandi una query in un unico posto e descrivi esattamente i dati che vuoi ricevere.
Selezionare campi (inclusi dati annidati)
Una query è sostanzialmente una "lista della spesa" di campi. Puoi richiedere campi semplici (come id e name) e anche dati annidati (come i post recenti di un utente) nella stessa richiesta — senza scaricare campi extra che non ti servono.
Ecco un piccolo esempio:
query GetUserWithPosts {
user(id: "123") {
id
name
posts(limit: 2) {
id
title
}
}
}
Una forma di risposta prevedibile
Le risposte GraphQL sono prevedibili: il JSON che ricevi rispecchia la struttura della query. Questo rende il lavoro sul frontend più semplice, perché non devi indovinare dove appariranno i dati o parsare formati di risposta diversi.
Un esempio semplificato potrebbe assomigliare a:
{
"data": {
"user": {
"id": "123",
"name": "Sam",
"posts": [
{ "id": "p1", "title": "Hello GraphQL" },
{ "id": "p2", "title": "Queries in Practice" }
]
}
}
}
Se non chiedi un campo, non verrà incluso. Se lo chiedi, puoi aspettarti di trovarlo nel punto corrispondente — questo rende le query GraphQL un modo pulito per prendere esattamente ciò che ogni schermata o funzionalità richiede.
Mutation: scrivere dati in modo sicuro
Le query servono per leggere; le mutation sono il modo per modificare i dati in un'API GraphQL — creare, aggiornare o cancellare record.
Il flusso tipico di una mutation
La maggior parte delle mutation segue lo stesso schema:
- Input: il client invia un input strutturato (spesso un oggetto
input) con i campi da aggiornare. - Validazione & autorizzazione: il server verifica requisiti, formati, unicità e permessi.
- Scrittura: il server esegue la modifica nel database (o chiama un altro servizio).
- Payload/return type: il server restituisce una forma prevedibile in modo che l'interfaccia possa aggiornarsi.
Perché le mutation restituiscono dati
Le mutation GraphQL di solito restituiscono dati intenzionalmente, invece di limitarsi a success: true. Restituire l'oggetto aggiornato (o almeno il suo id e i campi principali) aiuta l'interfaccia a:
- aggiornare subito la schermata senza un altro round-trip
- aggiornare le cache in modo sicuro (comune con client come Apollo Client)
- mostrare errori a livello di campo nel contesto
Un design comune è un tipo "payload" che include sia l'entità aggiornata sia eventuali errori.
Un esempio base di mutation
mutation UpdateEmail($input: UpdateUserEmailInput!) {
updateUserEmail(input: $input) {
user {
id
email
}
errors {
field
message
}
}
}
Per API orientate all'interfaccia, una buona regola è: restituisci ciò che serve per renderizzare lo stato successivo (per esempio l'user aggiornato più eventuali errors). Questo mantiene il client semplice, evita di indovinare cosa è cambiato e facilita la gestione degli errori.
Resolver: come GraphQL produce il risultato
Uno schema GraphQL descrive cosa si può chiedere. I resolver descrivono come ottenere effettivamente quei dati. Un resolver è una funzione collegata a un campo specifico nello schema. Quando un client richiede quel campo, GraphQL invoca il resolver per recuperare o calcolare il valore.
I resolver sono funzioni a livello di campo
GraphQL esegue una query percorrendo la forma richiesta. Per ogni campo, trova il resolver corrispondente e lo esegue. Alcuni resolver semplicemente ritornano una proprietà di un oggetto già in memoria; altri interrogano un database, chiamano un servizio o combinano più sorgenti.
Per esempio, se lo schema ha User.posts, il resolver posts potrebbe interrogare la tabella posts filtrando per userId, o chiamare un servizio Posts separato.
Mappare i campi dello schema alle sorgenti dati
I resolver sono il collante tra lo schema e i tuoi sistemi reali:
- Database: query SQL/NoSQL, stored procedure, chiamate ORM
- Servizi: chiamate REST/gRPC, microservizi interni, API di terze parti
- Campi calcolati: totali, formattazioni, valori derivati
Questa mappatura è flessibile: puoi cambiare l'implementazione backend senza modificare la forma della query client — purché lo schema rimanga coerente.
Prestazioni: evitare catene lente di resolver (N+1)
Poiché i resolver possono eseguire per campo e per elemento in una lista, è facile inavvertitamente generare molte chiamate piccole (ad esempio, recuperare post per 100 utenti con 100 query separate). Questo pattern "N+1" può rallentare le risposte.
Le soluzioni comuni includono batching e caching (es. raccogliere gli ID e recuperare in una singola query) e decidere intenzionalmente quali campi annidati incoraggiare i client a richiedere.
Dove avvengono autorizzazione e validazione
L'autorizzazione viene spesso applicata nei resolver (o in middleware condivisi) perché i resolver conoscono chi sta chiedendo (tramite il context) e quali dati si stanno accedendo. La validazione avviene a due livelli: GraphQL gestisce automaticamente la validazione di tipo/forma, mentre i resolver fanno rispettare le regole di business (per esempio, "solo gli admin possono impostare questo campo").
Errori e risultati parziali
Una cosa che sorprende chi è nuovo a GraphQL è che una richiesta può “riuscire” e comunque includere errori. Questo perché GraphQL è orientato ai campi: se alcuni campi si risolvono e altri no, potresti ottenere dati parziali.
Come si presentano gli errori
Una tipica risposta GraphQL può contenere sia data sia un array errors:
{
"data": {
"user": {
"id": "123",
"email": null
}
},
"errors": [
{
"message": "Not authorized to read email",
"path": ["user", "email"],
"extensions": { "code": "FORBIDDEN" }
}
]
}
Questo è utile: il client può comunque renderizzare ciò che ha (per esempio il profilo utente) gestendo il campo mancante.
Errori a livello di campo vs fallimenti a livello di richiesta
- Errori a livello di campo accadono durante l'esecuzione (un resolver lancia, il controllo di permessi fallisce, un servizio downstream va in timeout). Altri campi possono comunque risolversi.
- Fallimenti a livello di richiesta impediscono l'esecuzione (JSON non valido, query malformata, errori di validazione contro lo schema). In questi casi
dataè spessonull.
Messaggi user-friendly senza esporre dettagli interni
Scrivi messaggi di errore per l'utente finale, non per il debugging. Evita di esporre stack trace, nomi di database o ID interni. Un buon pattern è:
- Un
messagebreve e sicuro - Un
extensions.codeleggibile dalla macchina e stabile - Metadata opzionali che siano sicuri (ad esempio
retryable: true)
Logga l'errore dettagliato lato server con un request ID in modo da poter indagare senza esporre gli internals.
Consigli per una gestione coerente nei client
Definisci un piccolo "contratto" di errori condiviso tra web e mobile: valori comuni in extensions.code (come UNAUTHENTICATED, FORBIDDEN, BAD_USER_INPUT), quando mostrare una notifica vs un errore inline, e come trattare i dati parziali. La coerenza evita che ogni client inventi regole diverse.
Subscriptions per aggiornamenti in tempo reale
Le subscriptions sono il modo di GraphQL per inviare dati ai client mentre cambiano, invece di farli chiedere continuamente. Di solito sono veicolate su una connessione persistente (più comunemente WebSockets), così il server può inviare eventi non appena accadono.
Cosa sono le subscriptions (e come funzionano)
Una subscription somiglia molto a una query, ma il risultato non è una singola risposta. È un flusso di risultati — ognuno rappresenta un evento.
Sotto il cofano, un client si "iscrive" a un argomento (per esempio messageAdded in una chat). Quando il server pubblica un evento, i subscriber connessi ricevono un payload che rispecchia la selection set della subscription.
Use case comuni
Le subscriptions brillano quando si aspettano cambiamenti istantanei:
- Messaggi di chat che appaiono nella stanza senza refresh
- Notifiche (mention, cambiamento stato ordine, alert)
- Dashboard live (salute del sistema, logistica, trading, punteggi sportivi)
Subscriptions vs polling
Con il polling il client chiede “c'è qualcosa di nuovo?” ogni N secondi. È semplice, ma può sprecare richieste (soprattutto quando nulla cambia) e restituire aggiornamenti con ritardo.
Con le subscriptions, il server invia l'aggiornamento immediatamente. Questo può ridurre traffico inutile e migliorare la percezione di velocità — al costo di mantenere connessioni aperte e gestire l'infrastruttura realtime.
Quando le subscriptions sono complessità inutile
Le subscriptions non sono sempre giustificate. Se gli aggiornamenti sono rari, non urgenti o facilmente raggruppabili, il polling (o semplicemente rifetch dopo azioni utente) è spesso sufficiente.
Aggiungono anche overhead operativo: scalare le connessioni, autenticare sessioni di lunga durata, retry e monitoraggio. Una buona regola: usa subscriptions solo quando il realtime è un requisito di prodotto, non semplicemente un "nice-to-have".
Vantaggi, svantaggi e compromessi pratici
GraphQL viene spesso descritto come “potere al client”, ma quel potere ha dei costi. Conoscere i compromessi aiuta a decidere quando GraphQL è la scelta giusta — e quando può essere eccessivo.
Dove GraphQL dà il massimo
Il guadagno più grande è il recupero dati flessibile: i client possono richiedere esattamente i campi necessari, riducendo l'over-fetching e rendendo più rapide le modifiche UI.
Un altro vantaggio importante è il contratto forte fornito dallo schema GraphQL. Lo schema diventa una single source of truth per tipi e operazioni disponibili, migliorando collaborazione e tooling.
I team spesso vedono miglior produttività lato client perché gli sviluppatori frontend possono iterare senza aspettare nuove varianti di endpoint, e strumenti come Apollo Client possono generare tipi e semplificare il recupero dati.
Svantaggi comuni da pianificare
GraphQL può rendere il caching più complesso. Con REST il caching spesso si basa sull'URL. Con GraphQL molte query condividono lo stesso endpoint, quindi il caching dipende dalla forma della query, cache normalizzate e una configurazione attenta server/client.
Sul lato server ci sono trappole di prestazioni. Una query apparentemente piccola può scatenare molte chiamate backend a meno che non progetti i resolver con attenzione (batching, evitare pattern N+1 e controllare campi costosi).
C'è anche una curva di apprendimento: schemi, resolver e pattern client possono essere nuovi per i team abituati alle API basate su endpoint.
Sicurezza e operazioni
Poiché i client possono chiedere molto, le API GraphQL dovrebbero imporre limiti di profondità e complessità delle query per prevenire richieste abusive o accidentali troppo grandi.
Autenticazione e autorizzazione vanno applicate per campo, non solo a livello di rotta, dato che campi diversi possono avere regole di accesso diverse.
A livello operativo, investi in logging, tracing e monitoring che comprendano GraphQL: traccia nomi delle operazioni, variabili (con attenzione), tempi dei resolver e tassi di errore in modo da rilevare query lente e regressioni precocemente.
GraphQL vs REST: come differiscono
GraphQL e REST aiutano entrambe le app a parlare con i server, ma strutturano quella conversazione in modi molto diversi.
Come tipicamente funziona REST
REST è basato sulle risorse. Recuperi dati chiamando endpoint diversi (URL) che rappresentano "cose" come /users/123 o /orders?userId=123. Ogni endpoint restituisce una forma di dati fissa decisa dal server.
REST si appoggia anche alle semantiche HTTP: metodi come GET/POST/PUT/DELETE, codici di stato e regole di caching. Questo rende REST naturale quando fai CRUD semplici o lavori strettamente con cache del browser/proxy.
Come funziona GraphQL
GraphQL è basato sullo schema. Invece di molti endpoint, di solito hai un endpoint, e il client invia una query descrivendo i campi esatti che vuole. Il server valida la richiesta rispetto allo schema GraphQL e restituisce una risposta che corrisponde alla forma della query.
Questa "selezione guidata dal client" è il motivo per cui GraphQL può ridurre l'over-fetching e l'under-fetching, specialmente per schermate UI che necessitano dati da più modelli correlati.
Quando REST può essere più semplice
REST è spesso la scelta migliore quando:
- Hai bisogno di download/upload di file (streaming, content-type, richieste range).
- L'API è soprattutto CRUD semplice con payload prevedibili.
- Ti affidi molto al caching HTTP ai bordi e vuoi compatibilità massima con tooling esistente.
Gli approcci ibridi sono comuni
Molti team mescolano entrambi:
- Usa GraphQL per il recupero dati focalizzato sulla UI (web/mobile).
- Mantieni REST per servizi specifici come callback auth, webhook, gestione file o endpoint interni di microservizi.
La domanda pratica non è “Qual è meglio?” ma “Qual è più adatto a questo caso d'uso con la minor complessità?”.
Come progettare un'API GraphQL (checklist per principianti)
Progettare un'API GraphQL è più semplice se la tratti come un prodotto per chi costruisce schermate, non come uno specchio del tuo database. Parti in piccolo, convalida con casi d'uso reali ed espandi man mano che servono.
1) Parti dalle schermate (non dalle tabelle)
Elenca le schermate chiave (es. “Lista prodotti”, “Dettaglio prodotto”, “Checkout”). Per ogni schermata, annota i campi esatti di cui ha bisogno e le interazioni supportate.
Questo aiuta a evitare "query onnivore", riduce l'over-fetching e chiarisce dove servono filtraggio, ordinamento e paginazione.
2) Modella i tipi di dominio, poi aggiungi operazioni gradualmente
Definisci prima i tipi core (es. User, Product, Order) e le loro relazioni. Poi aggiungi:
- un piccolo set di query che rispecchiano schermate reali
- un piccolo set di mutation che rispecchiano azioni reali degli utenti ("addToCart", "placeOrder")
Preferisci nomi in linguaggio di business piuttosto che nomi legati al database. “placeOrder” comunica meglio l'intento rispetto a “createOrderRecord”.
3) Convenzioni di naming e paginazione
Mantieni naming coerente: singolare per singoli elementi (product), plurale per collezioni (products). Per la paginazione, di solito scegli una delle due:
- Cursor-based: migliore per liste che cambiano e per infinite scroll (più stabile)
- Offset-based: più semplice, ma può saltare/duplicare elementi quando i dati cambiano
Anche a livello alto, decidi presto perché influenza la struttura della risposta dell'API.
4) Documenta mentre costruisci
GraphQL supporta descrizioni direttamente nello schema — usale per campi, argomenti e casi particolari. Poi aggiungi alcuni esempi copy-paste nella documentazione (inclusa la paginazione e scenari di errore comuni). Uno schema ben descritto rende introspezione ed esploratori API molto più utili.
Per cominciare: strumenti, testing e passi successivi
Iniziare con GraphQL significa scegliere alcuni strumenti ben supportati e impostare un flusso di lavoro affidabile. Non devi adottare tutto subito — fai funzionare una query end-to-end, poi espandi.
Scegli un framework server
Scegli un server in base allo stack e a quanto "batteries included" vuoi:
- Apollo Server: scelta popolare con grande ecosistema e ottima documentazione.
- GraphQL Yoga: leggero, impostazioni moderne e ottima esperienza sviluppatore.
- NestJS: ideale se già usi Nest e vuoi GraphQL integrato con moduli, DI e pattern.
Un primo passo pratico: definisci un piccolo schema (un paio di tipi + una query), implementa i resolver e collega una sorgente dati reale (anche se è solo una lista in memoria).
Se vuoi muoverti più velocemente dall'idea a un'API funzionante, una piattaforma tipo Koder.ai può aiutarti a scaffoldare una piccola app full-stack (React frontend, Go + PostgreSQL backend) e iterare su schema/resolver via chat — poi esportare il codice quando sei pronto a gestirlo.
Scegli un approccio client
Sul frontend la scelta dipende spesso se preferisci convenzioni opinabili o flessibilità:
- Apollo Client: molto usato, caching solido e devtools.
- Relay: pattern più rigorosi, spesso usato in app grandi che cercano coerenza.
- urql: più leggero, componibile, buono per team che vogliono controllo.
Se stai migrando da REST, comincia usando GraphQL per una schermata o feature e tieni REST per il resto finché l'approccio non dimostra il suo valore.
Testing: schema + resolver + integrazione
Tratta lo schema come un contratto API. Livelli utili di test includono:
- Validazione dello schema (costruisci lo schema in CI; fallisci subito su tipi invalidi)
- Unit test dei resolver (mock delle sorgenti dati per verificare edge case e regole di auth)
- Test di integrazione (esegui operazioni GraphQL reali contro un server di test e un DB di test)
Prossimi passi
Per approfondire, continua con:
- /blog/graphql-vs-rest
- /blog/graphql-schema-design
Domande frequenti
Che cos'è GraphQL in parole semplici?
GraphQL è un linguaggio di query e un runtime per API. I client inviano una query che descrive esattamente i campi di cui hanno bisogno e il server ritorna una risposta JSON che rispecchia quella struttura.
È meglio pensarlo come uno strato tra i client e una o più sorgenti di dati (database, servizi REST, API di terze parti, microservizi).
Quale problema risolve GraphQL rispetto agli endpoint REST fissi?
GraphQL aiuta principalmente con:
- Over-fetching: ricevere più campi di quelli necessari per una schermata.
- Under-fetching: dover fare più richieste per comporre una vista.
Permettendo al client di richiedere solo campi specifici (inclusi campi annidati), GraphQL può ridurre il trasferimento di dati non necessario e semplificare il codice client.
Cosa non è GraphQL?
GraphQL non è:
- Un database (non immagazzina i dati).
- Automaticamente più veloce (può ridurre dati inutili, ma il lavoro sul server conta ancora).
- “REST 2.0” (è uno stile di API diverso con vantaggi e compromessi).
Trattalo come un contratto API più un motore di esecuzione, non come una bacchetta magica per prestazioni o storage.
Perché GraphQL usa spesso un endpoint singolo?
La maggior parte delle API GraphQL espone un endpoint singolo (spesso /graphql). Invece di avere più URL, invii operazioni diverse (query/mutation) allo stesso endpoint.
Implicazione pratica: caching e osservabilità si basano spesso su nome dell'operazione + variabili, non sull'URL.
Cos'è uno schema GraphQL e perché è importante?
Lo schema è il contratto dell'API. Definisce:
- Tipi (es.
User,Post) - Campi su quei tipi (es.
User.name) - Relazioni (es.
User.posts)
Essendo fortemente tipizzato, il server può validare le query prima di eseguirle e restituire errori chiari quando i campi non esistono.
Come funzionano le query GraphQL?
Le query GraphQL sono operazioni di lettura. Specifica i campi che ti servono e la risposta JSON rispecchia la struttura della query.
Consigli:
- Dai un nome alle operazioni (es.
query GetUserWithPosts) per debug e monitoraggio. - Usa argomenti per modellare i risultati (es.
posts(limit: 2)).
Come funzionano le mutation in GraphQL e perché restituiscono dati?
Le mutation sono operazioni di scrittura (create/update/delete). Uno schema comune è:
- Inviare un oggetto
input - Validare e autorizzare sul server
- Eseguire la scrittura
- Restituire un payload che include i dati aggiornati e eventuali errori
Restituire dati (non solo success: true) aiuta l'interfaccia a aggiornarsi subito e mantiene le cache coerenti.
Cosa sono i resolver e dove si applicano le regole di autenticazione e business?
I resolver sono funzioni a livello di campo che indicano come recuperare o calcolare ogni campo.
Nella pratica, i resolver possono:
- Interrogare un database
- Chiamare un servizio interno
- Chiamare un'API di terze parti
- Calcolare un valore derivato
L'autorizzazione viene spesso applicata nei resolver (o in middleware condivisi) perché sanno chi sta richiedendo e quali dati si stanno accedendo.
Come si evitano problemi di prestazioni comuni come le query N+1?
È facile creare un pattern N+1 (ad es. caricare i post separatamente per ciascuno di 100 utenti).
Mitigazioni comuni:
- Batching (raggruppare gli ID e caricare in una singola chiamata)
- Caching (per richiesta o condiviso)
- Essere selettivi sui campi annidati costosi
Misura i tempi dei resolver e controlla chiamate ripetute a servizi esterni durante una singola richiesta.
Perché una risposta GraphQL può includere sia dati che errori?
GraphQL può restituire dati parziali insieme a un array errors. Succede quando alcuni campi vengono risolti correttamente e altri no (es. campo proibito, timeout di un servizio downstream).
Buone pratiche:
- Messaggi
messagebrevi e sicuri per l'utente extensions.codestabili (es.FORBIDDEN,BAD_USER_INPUT)- Loggare gli errori dettagliati server-side con un request ID
I client devono decidere quando mostrare dati parziali o trattare l'operazione come fallita.