GraphQL: Linguaggio di query flessibile e runtime system per la vostra API web
Le applicazioni sul web utilizzano le API (Application Programming Interfaces) per poter scambiare e rielaborare dati. Quindi affinché altri servizi possano accedere al proprio progetto web, bisogna sviluppare e implementare un’interfaccia. A tal fine esistono alcuni standard consolidati, come SOAP e REST (Representational State Transfer), che stabiliscono una struttura di base per l’API facilmente gestibile con qualsiasi linguaggio di programmazione attuale. In particolare l’architettura suddetta è diventata la soluzione più utilizzata in assoluto negli ultimi anni grazie alla sua semplicità.
Anche se il successo dell’architettura REST è stato sorprendente, esistono valide alternative altrettanto convincenti come GraphQL. Il linguaggio di query e il runtime system di Facebook regge il confronto con SOAP e REST e i suoi vantaggi sono riscontrabili anche in caso di interrogazioni più complesse.
- Gestione record DNS
- Amministrazione SSL
- Documentazione API
Cos’è GraphQL?
GraphQL è un linguaggio di query sviluppato nel 2012 da Facebook simile a SQL che comprende il runtime system e il sistema dei tipi. Inizialmente fu ideato esclusivamente per un utilizzo aziendale interno a causa della trasformazione delle nuove app mobili di Facebook per iOS e Android, che mostravano prestazioni sempre più deboli e una complessità crescente. Il colosso ha dovuto trovare una soluzione adeguata in particolare per la distribuzione dei dati News Feed e per l’ottimizzazione della relazione tra le informazioni richieste e le query di server. Nel 2015 Facebook rese disponibile il codice sorgente di GraphQL: in quel momento regolamentò quasi tutti gli accessi ai dati delle app mobili. Dal 2017 il progetto va avanti sotto la licenza gratuita OWFa-1.0 (Open Web Foundation).
Come funziona GraphQL?
Per comprendere le modalità di funzionamento di GraphQL è importante occuparsi delle tre componenti basilari che caratterizzano il progetto open source:
- Linguaggio query: innanzitutto il GraphQL utilizza un linguaggio query (query language) che permette ai programmi un facile accesso a un’API. Mentre altre architetture di interfaccia accettano solo query molto rigorose che spesso forniscono l’accesso solo a una singola risorsa, le query di GraphQL sono caratterizzate da un elevato grado di flessibilità. Ciò dimostra concretamente che non esiste un limite per il numero di risorse interrogate e che è possibile definire quali campi di dati devono essere interrogati. GraphQL consente di leggere, scrivere e modificare le query.
- Sistema dei tipi: GraphQL lavora inoltre con un proprio sistema dei tipi che permette di descrivere la propria API attraverso tipi di dati. Le strutture dei dati così definite forniscono quindi la struttura reale per le query. Ogni tipo è costituito da uno o più campi che contengono proprie specifiche di tipo. Il singolo sistema così creato serve a GraphQL come punto d’orientamento per validare le richieste e poter respingere le query errate.
- Runtime system: GraphQL fornisce anche diversi runtime system di server per l’esecuzione delle query GraphQL. A tale scopo mette a disposizione librerie per diversi linguaggi di programmazione, come Go, Java, JavaScript, PHP, Python o Ruby. Si ha dunque libera scelta per quanto riguarda il linguaggio della propria API GraphQL. Il runtime system è tuttavia responsabile per la conversione e la validazione delle query, come anche per la serializzazione delle risposte (trasformazione degli oggetti in una sequenza di byte corrispondente). Tra i compiti dell’applicazione web rientrano anche il salvataggio e il reperimento di dati (ad es. in una banca dati).
Linguaggio di query, sistema dei tipi e runtime system forniscono insieme una struttura API altamente personalizzabile che non è disponbile solo per la piattaforma e l’applicazione, ma può essere anche perfettamente adattato alle specifiche della propria applicazione web: l’interfaccia GraphQL può essere infatti integrata senza problemi nel codice del vostro progetto, a prescindere dal fatto che utilizziate il framework Django in Python, quello Rails in Ruby o quello di JavaScript Node.js.
Quali sono le caratteristiche di GraphQL?
Una delle caratteristiche principali di GraphQL è la semplicità del linguaggio di query, che semplifica notevolmente agli sviluppatori l’accesso all’interfaccia. Chi si confronta con GraphQL constaterà molto presto che le risposte ricevute corrispondo una ad una alle richieste inviate. Il formato di output è snello quanto il diffuso formato JavaScript JSON (JavaScript Object Notation). Di conseguenza l’invio di una query personalizzata non rappresenta una grande impresa se si conosce la struttura dei dati richiesti dalla propria applicazione, formulati nella query. Oltre alla semplice redazione delle query, GraphQL è caratterizzato dalle seguenti funzionalità:
- Struttura gerarchica: i dati accessibili attraverso l’API di GraphQL hanno una struttura gerarchica. Si creano automaticamente dei rapporti tra i singoli oggetti, sulla base dei quali possono essere formulate anche query complesse (e ricevere risposte) in un’unica request. Lo scambio di più messaggi tra server e client (chiamato anche “round trip”) non è necessario. Questa gerarchia dei dati è adatta soprattutto per database a grafo, come JanusGraph, e per interfacce utente che sono strutturate per lo più gerarchicamente.
- Forte tipizzazione: ogni livello di query GraphQL corrisponde a un determinato tipo e ogni tipo descrive un set di campi disponibili. Questo sistema di tipi può tuttavia stabilire in modo più che automatico se una query è formulata correttamente o no: come SQL anche GraphQL, grazie alla sua rigorosa tipizzazione, può rispondere con messaggi di errore descrittivi già durante lo sviluppo e prima dell’invio della query.
- Flessibilità: GraphQL permette di creare query flessibili. Inoltre è possibile godere di una serie di libertà e vantaggi in fase di sviluppo, come anche personalizzare la propria interfaccia. Di solito sono disponibili poche personalizzazioni lato server, mentre il team di sviluppo può agire in modo completamente indipendente dal team responsabile per la componente client. Infine si possono eseguire tutte le variazioni o gli ampliamenti dell’API senza versioning, dato che i campi aggiuntivi possono essere inseriti facilmente e senza influire sui client esistenti.
GraphQL vs REST: cosa differenzia i due concetti API?
All’inizio abbiamo parlato del grande successo di REST nel World Wide Web e come GraphQL sia diventato una valida alternativa a questa architettura su base HTTP orientata alle risorse per i servizi web. Ciò è stato possibile in particolare grazie allo sviluppo che ha portato Facebook all’ideazione di GraphQL: l’importanza e la complessità crescenti delle applicazioni web mobili. La forza di GraphQL come base API si mostra in particolare nelle applicazioni per Android, iOS e simili: con una singola query si può ottenere l’accesso a tutti i dati desiderati.
L’istanza del server GraphQL fornisce esattamente le informazioni definite nella query, quindi non verranno inviati più o meno dati del necessario sull’interfaccia. Con le comparabili API di REST è possibile interrogare solo una serie specifica di dati per query, dopodiché questa viene inviata per intero. Nel confronto tra GraphQL e REST il concetto di query di Facebook si dimostra più preciso ed efficiente, il che torna utile per le prestazioni dell’applicazione. Ciò vale soprattutto per gli utenti dei dispositivi mobili, che non sempre hanno a disposizione connessioni Internet stabili e veloci.
Se da una parte la libertà delle query dei dati di GraphQL risulta essere una caratteristica molto positiva, dall’altra parte potrebbe causare un serio problema di sicurezza, soprattutto se si vogliono offrire API aperte, sulle quali non si può controllare il comportamento delle query da parte di client terzi. Quindi potrebbe verificarsi che un alto numero di query porti il server al collasso (intenzionalmente o meno). Uno scenario simile, da cui bisogna in ogni caso proteggersi, non risulta essere così minaccioso se si utilizza un’API di REST. Implementare GraphQL sul back-end di modo che funzioni velocemente e in sicurezza è quindi molto più difficile.
Inoltre anche l’implementazione di un processo di caching per query non mutevoli è significativamente più complicato con GraphQL in confronto alle query di un’interfaccia REST, in quanto queste possono essere salvate (ad esempio nel browser) mediante metodi di caching della specifica HTTP.
Tutorial di GraphQL: primi passi ed esempi
GraphQL offre un ampio margine di scelta del linguaggio di programmazione di base, grazie alla vasta gamma di librerie pronte all’uso. Ciò rappresenta anche uno dei grandi vantaggi nell’implementazione di un’interfaccia GraphQL nella propria app. Se siete fan di Python potete ricorrere ad esempio alla libreria Graphene o lavorare con la libreria graphql-java se il progetto è basato su Java. GraphQL.js è particolarmente adatto come base per l’implementazione se l’applicazione web si basa sul runtime system di JavaScript.
Sul sito internet di GraphQL troverete un elenco di tutte le librerie GraphQL disponibili e delle applicazioni client per i diversi linguaggi di programmazione.
Nel seguente tutorial di GraphQL spieghiamo con alcuni esempi come iniziare a utilizzare il framework di API per un’applicazione JavaScript, dove oltre alla suddetta libreria GraphQL.js viene utilizzato anche il framework web Express.
Passo n°1: Installazione della libreria
Per poter utilizzare le librerie GraphQL bisogna prima installarle. Per installare la libreria JavaScript GraphQL.js, si utilizza il gestore di pacchetti JavaScript npm (Node Package Manager) e il seguente comando:
npm install --save graphql
In alternativa la libreria può anche appoggiarsi sul package manager Yarn, sviluppato da Facebook (prevalentemente) e Google.
yarn add graphql
In entrambi i casi il presupposto è l’installazione di una versione attuale di Node.js (è consigliato Node v6.0.0 o superiore).
Passo n°2: Il primo schema di query
Affinché la vostra applicazione possa elaborare query GraphQL ha bisogno di uno schema che definisce il tipo di query e il punto d’accesso alla vostra interfaccia (chiamato anche API root) compreso di funzione resolver. Per un esempio di interfaccia GraphQL semplice da cui si genera il messaggio “Ciao mondo!”, il codice corretto nel file server.js è il seguente:
var { graphql, buildSchema } = require('graphql');
// Costruisci uno schema sulla base del concetto GraphQL
var schema = buildSchema(`
type Query {
hello: String
}
`);
// API root mette a disposizione una funzione resolver per ciascun end point attingente
var root = {
hello: () => {
return 'Ciao mondo!';
},
};
// Esegui la richiesta GraphQL '{ hello }' e riproduci la rispettiva risposta
graphql(schema, '{ hello }', root).then(response => {
console.log(response);
});
Se si esegue questo codice con Node.js, mentre si inserisce il comando
node server.js
sul terminale dovrebbe apparire il seguente messaggio:
{ data: { hello: Ciao mondo!' } }
Passo n°3: Server GraphQL su base Express
Non appena è stata creata una semplice query ed è stata eseguita nella riga di comando, è arrivato il momento di far funzionare un server API di GraphQL. È ora necessario raggiungere l’interfaccia utilizzando ad esempio un browser web standard. A tale scopo installate il framework di installazione Express e l’altrettanto necessaria libreria express-graphql con il seguente comando:
npm install express express-graphql --save
Quindi modificate l’esempio GraphQL “Ciao mondo!” affinché diventi la base del vostro server GraphQL invece di un semplice script. A tale scopo implementate il modulo Express e utilizzate la libreria express-graphql per collegare il server API all’end point HTTP “/graphql”:
var express = require('express');
var graphqlHTTP = require('express-graphql');
var { buildSchema } = require('graphql');
// Costruisci uno schema sulla base del concetto GraphQL
var schema = buildSchema(`
type Query {
hello: String
}
`);
// API root mette a disposizione una funzione resolver per ciascun end point attingente
var root = {
hello: () => {
return Ciao mondo!';
},
};
var app = express();
app.use('/graphql', graphqlHTTP({
schema: schema,
rootValue: root,
graphiql: true
}));
app.listen(4000);
console.log('Eseguire server API GraphQL su localhost:4000/graphql');
Come nell’esempio GraphQL precedente, aprite il file server.js con Node.js, con la differenza che questa volta non eseguite una semplice query, ma avviate il vostro server API:
node server.js
Nel codice del server Express di GraphQL non sono specificati solo lo schema e l’API root, ma è rappresentato anche l’end point HTTP “/graphql”. Con l’input “graphiql: true” viene attivato l’omonimo tool che permette l’inserimento di query attraverso un’interfaccia grafica utente. Aprite semplicemente il vostro browser e inserite il seguente indirizzo:
http://localhost:4000/graphql
Dopo aver installato i componenti importanti seguendo passo dopo passo questo tutorial GraphQL, redatto il vostro primo schema di query e avviato il vostro primo server, potete familiarizzare con le opzioni di inserimento delle query.
Troverete ulteriori informazioni e spiegazioni più dettagliate riguardo alla configurazione dei backend e frontend di GraphQL nella pagina dei tutorial sul sito web ufficiale dell’API di Facebook.