GraphQL — cos'è, linguaggio di query e applicazione nei progetti mobile

Autore: IT Sectr Pubblicato: 2026-03-06 Tempo di lettura: 9 min

GraphQL — è un linguaggio di query per API e un runtime per eseguire tali query, sviluppato da Facebook nel 2012 e reso open source nel 2015. A differenza di REST, dove il server determina la struttura della risposta, GraphQL consente al client di specificare esattamente i dati di cui ha bisogno, eliminando completamente i problemi di overfetching e underfetching. Secondo il State of JavaScript Survey (2025), il 35% degli sviluppatori intervistati utilizza GraphQL, e tra le grandi aziende lo hanno adottato GitHub, Shopify, Airbnb e The New York Times. GraphQL supporta tre tipi di operazioni: query (lettura), mutation (scrittura) e subscription (aggiornamenti in tempo reale via WebSocket).

Punti chiave

  • GraphQL — un linguaggio di query dove il client specifica la struttura della risposta
  • Risolve i problemi di overfetching (dati superflui) e underfetching (dati insufficienti)
  • Supporta query, mutation e subscription per diversi tipi di operazioni
  • Utilizza un unico endpoint (solitamente /graphql) invece di più URL come in REST
  • Si basa su un sistema di tipi con uno schema rigoroso: tutti i dati possibili sono descritti in anticipo

Cos'è GraphQL?

GraphQL — è una specifica e un runtime per API che dà al client il controllo completo sui dati ricevuti. Sviluppata dagli ingegneri di Facebook per risolvere i problemi dell'applicazione mobile News Feed, la specifica è stata pubblicata come standard aperto nel 2015. Dal 2018, GraphQL è gestito dalla GraphQL Foundation con il supporto della Linux Foundation e di aziende come Apollo, AWS, GitHub, SAP e altre.

A differenza di REST, dove ogni endpoint restituisce una struttura dati fissa, GraphQL utilizza un unico endpoint che accetta una stringa di query. Il client descrive nella query quali campi gli servono e il server restituisce esattamente quelli. Ad esempio, la query { user(id: "1") { name email } } restituirà solo il nome e l'email dell'utente, senza campi aggiuntivi come address, phone o createdAt che sarebbero stati necessari in REST.

GraphQL non è legato a nessun database o linguaggio specifico. La specifica definisce solo il formato delle query e delle risposte. Esistono implementazioni server su Node.js (graphql-js, Apollo Server), Kotlin (graphql-kotlin, Netflix DGS Framework), Python (Graphene, Strawberry), Ruby (graphql-ruby) e altri linguaggi. Le librerie client sono disponibili per tutte le principali piattaforme, incluso Apollo Client per iOS, Android e web.

Come funziona GraphQL

L'architettura di GraphQL è composta da tre componenti chiave: Schema, Resolver e il Motore GraphQL (GraphQL Engine). Lo schema definisce quali tipi di dati sono disponibili, quali query possono essere eseguite e quali argomenti accettano. I resolver sono funzioni lato server che restituiscono dati per ogni campo dello schema. Il motore riceve la query in ingresso, la valida rispetto allo schema, chiama i resolver appropriati e assembla la risposta.

Il processo di elaborazione della query è il seguente:

  • Il client invia una richiesta POST a /graphql con un corpo JSON { "query": "..." }
  • Il server analizza la query, costruisce un AST (Albero Sintattico Astratto) e lo valida rispetto allo schema
  • Il motore attraversa l'AST, chiamando i resolver per ogni campo, raccogliendo dati
  • La risposta viene restituita in formato JSON, corrispondente rigorosamente alla struttura della query

Il vantaggio chiave dell'architettura GraphQL è la risoluzione a livello di campo. In REST, lo sviluppatore ottiene tutti i campi di una risorsa (possibilmente con dati superflui) o ricorre a estensioni come ?fields=name,email. In GraphQL, questo filtraggio è integrato nel linguaggio: ogni query specifica esplicitamente quali campi sono necessari e il server restituisce esattamente quelli. Ciò è particolarmente importante per le applicazioni mobili, dove la quantità di dati trasferiti influisce direttamente sulla velocità di caricamento e sul consumo di dati.

Query, Mutation e Subscription

GraphQL definisce tre tipi di operazioni, ciascuno corrispondente a uno scenario di interazione specifico. Query — per la lettura dei dati, analogo a GET in REST. Mutation — per modificare i dati (creazione, aggiornamento, eliminazione), analogo a POST/PUT/DELETE. Subscription — per aggiornamenti in tempo reale via WebSocket, che non ha un analogo diretto nel REST classico (richiede soluzioni aggiuntive come WebSocket o Server-Sent Events).

La sintassi di base delle query è intuitiva:

js
// Query semplice con argomento
query {
    user(id: "42") {
        name
        email
        avatarUrl
    }
}

// Mutation che restituisce dati modificati
mutation {
    updateProfile(name: "Ivan") {
        id
        name
        updatedAt
    }
}

// Subscription — ascolta gli aggiornamenti in tempo reale
subscription {
    newMessage(chatId: "chat_1") {
        id
        text
        sender { name }
    }
}

Query viene eseguita in parallelo — tutti i campi allo stesso livello vengono caricati simultaneamente. Ciò consente di caricare dati correlati (utente e i suoi post) in un'unica richiesta senza più round-trip. Mutation viene eseguita sequenzialmente — le mutazioni in una richiesta vengono eseguite una dopo l'altra nell'ordine di dichiarazione. Subscription stabilisce una connessione persistente via WebSocket, attraverso la quale il server invia dati al verificarsi di un evento.

Le operazioni possono accettare variabili per separare i dati dalla query, direttive (@include, @skip) per l'inclusione condizionale di campi e frammenti per riutilizzare insiemi di campi. Queste capacità rendono le query GraphQL flessibili e riutilizzabili, il che è particolarmente importante nei grandi progetti con molti schermi e componenti.

Schema e sistema di tipi di GraphQL

Al centro di GraphQL c'è un sistema di tipi che descrive tutti i dati e le operazioni API possibili. Lo schema è una descrizione dei tipi che il server può restituire e delle query che accetta. Lo schema è scritto in Schema Definition Language (SDL) e funge da contratto tra client e server. Il client può ottenere lo schema tramite introspezione — una query speciale __schema che restituisce una descrizione completa dell'API.

Esempio di schema per un blog:

js
// SDL — Schema Definition Language
type User {
    id: ID!
    name: String!
    email: String
    posts: [Post!]!
}

type Post {
    id: ID!
    title: String!
    content: String
    author: User!
}

type Query {
    user(id: ID!): User
    posts(page: Int): [Post!]!
}

Il punto esclamativo (!) indica un campo non nullo — sarà garantitamente presente nella risposta. Le parentesi quadre [ ] denotano un elenco. GraphQL supporta tipi scalari (Int, Float, String, Boolean, ID), tipi oggetto, enum, union, interface e tipi di input (per gli argomenti delle mutazioni). La tipizzazione rigorosa auto-documenta l'API e consente agli strumenti client di generare codice: tipi TypeScript, classi dati Kotlin, strutture Swift.

L'introspezione è una funzionalità unica di GraphQL assente in REST. Il client può inviare una query allo schema e ottenere una descrizione completa di tutti i tipi, campi, argomenti e direttive. Questa è la base di strumenti come GraphiQL e Apollo Studio, che generano automaticamente documentazione e completamento automatico per gli sviluppatori. L'introspezione consente anche di scrivere test automatici che verificano la conformità dello schema alla struttura prevista.

Confronto tra GraphQL e REST

La scelta tra GraphQL e REST è una delle decisioni architetturali chiave nella progettazione di un'API. Entrambi gli approcci hanno i loro punti di forza e di debolezza, e la scelta dipende dai requisiti specifici del progetto. REST vince in semplicità e universalità, GraphQL in flessibilità ed efficienza delle query. Diamo un'occhiata alla tabella comparativa.

CriterioRESTGraphQL
Struttura della rispostaFissa, definita dal serverFlessibile, definita dal client
OverfetchingSpesso — il server restituisce tutti i campiNo — il client richiede solo i campi necessari
Numero di richiestePiù round-tripUn'unica richiesta per tutti i dati
CacheCache HTTP nativaRichiede configurazione manuale
TipizzazioneNon integrata (dipende dal formato)Rigorosa, tramite schema SDL
Strumenticurl, Postman, SwaggerGraphiQL, Apollo Studio, Introspezione
Caricamento fileNativo tramite multipartRichiede protocolli aggiuntivi
PrestazioniPrevedibili, più facili da ottimizzareDipende dalla complessità delle query annidate

Il principale svantaggio di GraphQL è la complessità della cache. In REST, la cache HTTP funziona a livello di URL: una richiesta a /api/users/42 restituisce sempre la stessa struttura e la risposta può essere memorizzata nella cache per URL. In GraphQL, tutte le richieste vanno a un unico endpoint e la struttura della risposta dipende dal corpo della richiesta. Per risolvere questo problema, Apollo Client utilizza una cache normalizzata lato client, che suddivide le risposte in entità individuali per id e le aggiorna automaticamente al ricevimento di nuovi dati.

Un altro aspetto importante è il problema N+1. Quando si richiedono dati annidati (ad esempio, i post di un utente e i commenti per ogni post), GraphQL può eseguire una query SQL separata per ogni elemento dell'elenco. Viene risolto utilizzando DataLoader — un'utilità per raggruppare e memorizzare nella cache le query del database, che raggruppa le richieste individuali in un unico lotto. In REST, questo problema è meno pronunciato poiché lo sviluppatore controlla la struttura della risposta lato server.

Esempi di query GraphQL

Vediamo esempi pratici di utilizzo di GraphQL in un'applicazione mobile Kotlin con Apollo Client. Gli esempi mostrano scenari tipici: caricamento dei dati per una schermata del profilo (query), creazione di un nuovo post (mutation) e sottoscrizione a nuovi commenti (subscription). Ogni esempio include sia la query GraphQL che il codice lato client.

Query: Caricamento del profilo con post

Un'unica query GraphQL carica l'utente, i suoi ultimi post e il numero totale di follower. In REST, sarebbero necessarie almeno 2-3 richieste: /users/42, /users/42/posts, /users/42/stats. GraphQL le combina in un unico round-trip, riducendo il tempo di caricamento dello schermo su connessioni lente.

kotlin
// Query GraphQL (nel file .graphql)
query ProfileScreen($userId: ID!) {
    user(id: $userId) {
        name
        bio
        avatarUrl
        posts(limit: 10) {
            id
            title
            createdAt
        }
        followersCount
        followingCount
    }
}

// Chiamata sul client (Apollo Client + Kotlin)
val response = apolloClient
    .query(ProfileScreenQuery(userId = "42"))
    .execute()
binding.nameText.text = response.data?.user?.name

Mutation: Creazione di un nuovo post

La mutazione non solo crea una risorsa, ma restituisce anche i suoi dati correnti per aggiornare l'interfaccia utente. Il campo __typename è utilizzato da Apollo Client per la normalizzazione della cache — il client aggiornerà automaticamente il record Post nella cache in caso di risposta positiva della mutazione.

kotlin
// Mutation GraphQL
mutation CreatePost($input: CreatePostInput!) {
    createPost(input: $input) {
        id
        title
        createdAt
        author {
            id
            name
        }
    }
}

// Chiamata mutation con tipo input
val input = CreatePostInput(
    title = "Nuovo post su GraphQL",
    content = "GraphQL semplifica il lavoro con le API..."
)
val result = apolloClient
    .mutation(CreatePostMutation(input))
    .execute()

Un importante vantaggio di GraphQL rispetto a REST nel contesto dello sviluppo mobile è la generazione automatica del codice. Apollo Client per Kotlin (Apollo GraphQL) genera classi type-safe da file .graphql in fase di compilazione. Se il server modifica lo schema, il progetto non verrà compilato fino all'aggiornamento delle query. Ciò previene errori a runtime tipici di REST, dove le modifiche alla struttura della risposta possono passare inosservate durante lo sviluppo.

Ecosistema: Apollo, Relay e strumenti

L'ecosistema GraphQL include diverse librerie e strumenti chiave che semplificano lo sviluppo e l'operatività. Apollo Client è la libreria client più popolare, che supporta React, iOS, Android e Kotlin Multiplatform. Relay di Facebook è un'alternativa per applicazioni React con un approccio unico alla gestione dei dati e alla cache. La scelta tra Apollo e Relay dipende dalla piattaforma e dai requisiti di prestazioni.

Lato server, i leader sono Apollo Server (Node.js), Netflix DGS Framework (Kotlin/Java) e graphql-ruby. Per lo sviluppo dello schema e il test delle query, viene utilizzato GraphiQL — un IDE interattivo integrato nel browser. Apollo Studio fornisce metriche delle prestazioni, tracciamento delle query e gestione dello schema per ambienti di produzione. Menzione a parte merita GraphQL Code Generator — uno strumento che genera tipi TypeScript, Kotlin, Swift e Dart da uno schema SDL.

Per lo sviluppo mobile, Apollo Kotlin (Apollo GraphQL) è di particolare interesse — una libreria interamente scritta in Kotlin con supporto per coroutine, Flow e Multiplatform. Consente di utilizzare query GraphQL unificate per Android e iOS in progetti Kotlin Multiplatform. Apollo Kotlin normalizza la cache, supporta errori a livello di campo (errori parziali) e genera automaticamente modelli di dati da file .graphql. Ciò rende GraphQL la scelta preferita per grandi progetti mobili dove la velocità di sviluppo e la sicurezza dei tipi sono importanti.

Domande frequenti

GraphQL sostituisce REST?

GraphQL non sostituisce REST, ma offre un approccio alternativo. REST è più adatto per API CRUD semplici, cache HTTP e API pubbliche con carico prevedibile. GraphQL è ottimale per interfacce complesse con molti dati correlati.

È difficile migrare da REST a GraphQL?

La migrazione è possibile gradualmente: GraphQL può funzionare come un livello (gateway) davanti ai servizi REST esistenti. Molte aziende aggiungono GraphQL accanto a REST senza disattivare la vecchia API. La sostituzione completa richiede la riscrittura dei resolver.

Cos'è il problema N+1 in GraphQL?

Il problema N+1 si verifica quando viene eseguita una query SQL separata per ogni elemento di un elenco. Viene risolto utilizzando DataLoader — una libreria che raggruppa le richieste individuali in una sola e memorizza nella cache i risultati all'interno di una singola richiesta HTTP.

Come gestisce GraphQL il caricamento dei file?

La specifica GraphQL non definisce direttamente il caricamento dei file. In pratica, vengono utilizzati: codifica base64 (semplice ma inefficiente per file grandi), richieste multipart secondo il protocollo graphql-multipart-request-spec o un endpoint REST separato per i file.

GraphQL è sicuro?

La sicurezza di GraphQL richiede misure aggiuntive: limitazione della profondità di annidamento, limiti di complessità delle query, rate limiting a livello di operazione. L'introspezione pubblica dello schema può rivelare la struttura dei dati — in produzione si consiglia di disabilitarla.

Riepilogo

  • GraphQL — un linguaggio di query dove il client controlla la struttura della risposta, eliminando overfetching e underfetching
  • Tre tipi di operazioni: query (lettura), mutation (scrittura), subscription (tempo reale)
  • Utilizza un unico endpoint e un sistema di tipi rigoroso — schema SDL
  • A differenza di REST, risolve il problema dei round-trip multipli — tutti i dati in una richiesta
  • Richiede DataLoader per prevenire il problema N+1 e configurazione manuale della cache
  • Client principali: Apollo Client (Android, iOS, Web) e Relay (React)
  • Più adatto per interfacce complesse con molte entità correlate e applicazioni mobili

Svilupperemo un'applicazione mobile chiavi in mano

IT Sectr crea applicazioni iOS e Android per startup e aziende dal 2017. Ti consulteremo e ti proporremo la soluzione migliore.

Discuti il progetto

Leggi anche