Guida Completa a URQL: Un Client GraphQL per Applicazioni React
URQL è un client GraphQL semplice e altamente personalizzabile per React che ti permette di interagire con API GraphQL in modo efficiente. Fornisce un set di strumenti per gestire query, mutazioni, subscriptions e persino cache, ottimizzando le prestazioni e riducendo la complessità . In questo articolo esploreremo come configurare URQL in un’applicazione React, come gestire le query e le mutazioni, e vedremo alcune funzionalità avanzate come la gestione della cache e le subscriptions.
Cos’è URQL?
URQL (Universal React Query Library) è un client GraphQL leggero per React che semplifica l’integrazione con API GraphQL. Offre un’API intuitiva, supporta l’ottimizzazione delle prestazioni tramite cache, e ha un sistema di middleware che consente di estenderne le funzionalità , come l’aggiunta di autenticazione o la gestione avanzata degli errori.
Perché Usare URQL?
- Semplice da Configurare: URQL richiede una configurazione minima per iniziare.
- Personalizzabile: Attraverso l’utilizzo di “exchanges” (intercettori) puoi personalizzare il comportamento del client.
- Performante: Supporta la caching e il refetching automatico.
- Estensibile: Facilmente estensibile con middleware personalizzati.
Installazione di URQL
Per iniziare con URQL in un’applicazione React, dobbiamo installare le dipendenze necessarie.
Installazione
npm install urql graphql
- urql: Il client URQL per React.
- graphql: La libreria GraphQL necessaria per inviare query al server.
Configurazione di Base di URQL
Dopo l’installazione, il primo passo è configurare il provider URQL per la tua applicazione React. Il provider gestisce la connessione al server GraphQL e rende disponibile URQL all’interno dell’app.
Esempio di Configurazione di Base
import React from "react";
import ReactDOM from "react-dom";
import { createClient, Provider } from "urql";
const client = createClient({
url: "https://my-graphql-api.com/graphql",
});
const App = () => (
<Provider value={client}>
<MyComponent />
</Provider>
);
ReactDOM.render(<App />, document.getElementById("root"));
In questo esempio:
- createClient crea un’istanza del client URQL, configurata per comunicare con l’endpoint GraphQL.
- Il client viene passato al Provider, che rende URQL disponibile a tutti i componenti figli.
Eseguire una Query con URQL
Per eseguire una query GraphQL, URQL fornisce il hook useQuery
, che consente di inviare una query e ricevere i risultati in modo asincrono.
Esempio di Query con useQuery
import { useQuery } from "urql";
import React from "react";
const UsersQuery = `
query {
users {
id
name
email
}
}
`;
const UsersList = () => {
const [result] = useQuery({ query: UsersQuery });
if (result.fetching) return <p>Loading...</p>;
if (result.error) return <p>Oh no... {result.error.message}</p>;
return (
<ul>
{result.data.users.map((user) => (
<li key={user.id}>
{user.name} - {user.email}
</li>
))}
</ul>
);
};
export default UsersList;
In questo esempio:
useQuery
invia la query GraphQL definita inUsersQuery
per recuperare una lista di utenti.- Il risultato viene gestito con uno stato che contiene
fetching
,error
edata
.
Risultato dell’Esecuzione
Il componente UsersList
mostrerà un messaggio di caricamento mentre la query è in esecuzione e, una volta completata, visualizzerà una lista di utenti. In caso di errore, mostrerà un messaggio d’errore.
Eseguire una Mutazione con URQL
URQL gestisce le mutazioni con il hook useMutation
. Una mutazione modifica i dati sul server e di solito richiede un input (es. creare o aggiornare un elemento).
Esempio di Mutazione con useMutation
import { useMutation } from "urql";
import React, { useState } from "react";
const AddUserMutation = `
mutation($name: String!, $email: String!) {
addUser(name: $name, email: $email) {
id
name
}
}
`;
const AddUser = () => {
const [name, setName] = useState("");
const [email, setEmail] = useState("");
const [, executeMutation] = useMutation(AddUserMutation);
const handleSubmit = (e) => {
e.preventDefault();
executeMutation({ name, email });
};
return (
<form onSubmit={handleSubmit}>
<input
value={name}
onChange={(e) => setName(e.target.value)}
placeholder="Name"
/>
<input
value={email}
onChange={(e) => setEmail(e.target.value)}
placeholder="Email"
/>
<button type="submit">Add User</button>
</form>
);
};
export default AddUser;
In questo esempio:
useMutation
viene utilizzato per definire e inviare la mutazioneAddUserMutation
.- Gli input
name
eemail
vengono passati come variabili alla mutazione per creare un nuovo utente.
Gestione della Cache con URQL
URQL include un sistema di cache integrato per ottimizzare le prestazioni delle query, evitando richieste ridondanti. Quando una query viene eseguita, URQL memorizza i risultati nella cache, così successive richieste per gli stessi dati possono essere risolte senza effettuare nuove chiamate al server.
Configurazione della Cache
import { cacheExchange } from "@urql/exchange-graphcache";
import { createClient, Provider } from "urql";
const client = createClient({
url: "https://my-graphql-api.com/graphql",
exchanges: [cacheExchange()],
});
const App = () => (
<Provider value={client}>
<MyComponent />
</Provider>
);
In questo esempio:
- La cache viene abilitata utilizzando l’
exchange
cacheExchange()
, che memorizza i risultati delle query nella cache.
Subscriptions con URQL
Le subscriptions permettono di ricevere aggiornamenti in tempo reale da un server GraphQL. URQL supporta le subscriptions utilizzando il hook useSubscription
e una connessione WebSocket.
Esempio di Subscription
npm install @urql/exchange-graphcache urql-ws
import { useSubscription } from "urql";
const NewMessageSubscription = `
subscription {
newMessage {
id
content
author
}
}
`;
const handleSubscription = (messages = [], response) => {
return [...messages, response.newMessage];
};
const MessagesList = () => {
const [result] = useSubscription(
{ query: NewMessageSubscription },
handleSubscription
);
if (!result.data) return <p>No messages yet...</p>;
return (
<ul>
{result.data.map((message) => (
<li key={message.id}>
{message.content} by {message.author}
</li>
))}
</ul>
);
};
export default MessagesList;
In questo esempio:
useSubscription
ascolta gli aggiornamenti del server e aggiunge nuovi messaggi alla lista esistente usando la funzionehandleSubscription
.- Ogni volta che un nuovo messaggio viene ricevuto, viene automaticamente aggiunto alla UI.
Middleware e Exchanges Personalizzati
URQL supporta exchanges, che sono simili ai middleware. Gli exchanges ti permettono di estendere il comportamento predefinito di URQL per gestire funzionalità come l’autenticazione, il logging o la modifica delle richieste.
Esempio di Middleware per Autenticazione
import { createClient, dedupExchange, fetchExchange } from 'urql';
const authExchange = ({ forward }) => (operations$) => {
return operations$.map((operation) => {
const token = localStorage.getItem('token');
if (token) {
operation.context = {
...operation.context,
fetchOptions: {
headers: {
Authorization: `Bearer ${token}`,
},
},
};
}
return forward(operation);
});
};
const client = createClient({
url: 'https://my-graphql-api.com
/graphql',
exchanges: [dedupExchange, authExchange, fetchExchange],
});
In questo esempio:
- L’exchange
authExchange
aggiunge automaticamente un token di autenticazione JWT alle richieste GraphQL, se presente nellocalStorage
.
Conclusione
URQL è un client GraphQL potente, flessibile e altamente personalizzabile, ideale per applicazioni React. Grazie alla sua semplicità e alla possibilità di estensione, URQL semplifica la gestione delle query, mutazioni e subscriptions, e offre strumenti avanzati per migliorare le prestazioni tramite caching e middleware personalizzati. Seguendo questa guida, puoi integrare facilmente URQL nel tuo progetto React e creare applicazioni performanti e reattive con GraphQL.