Implementare Subscriptions in Apollo GraphQL: Guida Passo-Passo
Le subscriptions in GraphQL permettono ai client di ricevere aggiornamenti in tempo reale da un server, rendendole uno strumento fondamentale per applicazioni che richiedono funzionalità come notifiche in tempo reale, aggiornamenti live e molto altro. Apollo è una delle librerie più popolari per lavorare con GraphQL e offre un supporto robusto per le subscriptions. In questa guida, vedremo come implementare le subscriptions utilizzando Apollo Server e Apollo Client.
Prerequisiti
Prima di iniziare, assicurati di avere i seguenti prerequisiti:
- Node.js installato
- Conoscenza di base di GraphQL e Apollo Server/Client
- Un progetto Node.js con Apollo Server già configurato
Se non hai ancora configurato un progetto con Apollo Server, puoi iniziare creando un nuovo progetto e installando le dipendenze necessarie:
npm init -y
npm install apollo-server graphql
Step 1: Configurazione di Apollo Server
Installazione delle Dipendenze
Per abilitare le subscriptions in Apollo Server, avrai bisogno di alcune librerie aggiuntive. In particolare, dovrai installare graphql-subscriptions
per gestire la logica delle subscriptions e ws
per il supporto WebSocket:
npm install graphql-subscriptions ws
Configurazione di base di Apollo Server con Subscriptions
Ecco come configurare Apollo Server per supportare le subscriptions:
const { ApolloServer, gql } = require("apollo-server");
const { PubSub } = require("graphql-subscriptions");
const { createServer } = require("http");
const { WebSocketServer } = require("ws");
const { useServer } = require("graphql-ws/lib/use/ws");
// Inizializza PubSub per gestire gli eventi
const pubsub = new PubSub();
// Definisci il tuo schema
const typeDefs = gql`
type Message {
id: ID!
content: String!
}
type Query {
messages: [Message!]
}
type Mutation {
postMessage(content: String!): ID!
}
type Subscription {
messagePosted: Message!
}
`;
// Simula un database in memoria
let messages = [];
let idCount = 1;
// Definisci i resolver
const resolvers = {
Query: {
messages: () => messages,
},
Mutation: {
postMessage: (_, { content }) => {
const id = idCount++;
const message = { id, content };
messages.push(message);
pubsub.publish("MESSAGE_POSTED", { messagePosted: message });
return id;
},
},
Subscription: {
messagePosted: {
subscribe: () => pubsub.asyncIterator(["MESSAGE_POSTED"]),
},
},
};
// Crea un'istanza di Apollo Server
const server = new ApolloServer({ typeDefs, resolvers });
// Crea un server HTTP
const httpServer = createServer(server);
// Inizializza WebSocket Server per le subscriptions
const wsServer = new WebSocketServer({
server: httpServer,
path: "/graphql",
});
useServer({ schema: server.schema }, wsServer);
// Avvia il server
server.start().then(() => {
httpServer.listen(4000, () => {
console.log("Server is running on http://localhost:4000/graphql");
});
});
Spiegazione del Codice
- PubSub: Un semplice sistema di pubblicazione/sottoscrizione in memoria fornito da
graphql-subscriptions
. - WebSocketServer: Un server WebSocket necessario per gestire le subscriptions.
- useServer: Una funzione di
graphql-ws
che collega il WebSocket server con Apollo Server per gestire le subscriptions.
Step 2: Configurazione del Client
Per ricevere le subscriptions sul client, utilizzeremo Apollo Client insieme a graphql-ws. Ecco come configurarlo.
Installazione delle Dipendenze
Prima di tutto, installa le dipendenze necessarie:
npm install @apollo/client graphql-ws
Configurazione del Client Apollo
Ecco un esempio di configurazione di Apollo Client con supporto per le subscriptions:
import {
ApolloClient,
InMemoryCache,
ApolloProvider,
split,
HttpLink,
} from "@apollo/client";
import { GraphQLWsLink } from "@apollo/client/link/subscriptions";
import { createClient } from "graphql-ws";
import { getMainDefinition } from "@apollo/client/utilities";
import React from "react";
import ReactDOM from "react-dom/client";
import App from "./App";
// Configura il link HTTP per le query e le mutazioni
const httpLink = new HttpLink({
uri: "http://localhost:4000/graphql",
});
// Configura il link WebSocket per le subscriptions
const wsLink = new GraphQLWsLink(
createClient({
url: "ws://localhost:4000/graphql",
})
);
// Utilizza la funzione split per instradare correttamente le richieste in base al tipo di operazione
const splitLink = split(
({ query }) => {
const definition = getMainDefinition(query);
return (
definition.kind === "OperationDefinition" &&
definition.operation === "subscription"
);
},
wsLink,
httpLink
);
// Configura Apollo Client
const client = new ApolloClient({
link: splitLink,
cache: new InMemoryCache(),
});
// Usa ApolloProvider per fornire il client alla tua app React
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
<ApolloProvider client={client}>
<App />
</ApolloProvider>
);
Esempio di Utilizzo nel Client
Ecco come utilizzare una subscription nel tuo componente React:
import { useSubscription, gql } from "@apollo/client";
const MESSAGE_POSTED_SUBSCRIPTION = gql`
subscription OnMessagePosted {
messagePosted {
id
content
}
}
`;
function Messages() {
const { data, loading } = useSubscription(MESSAGE_POSTED_SUBSCRIPTION);
if (loading) return <p>Loading...</p>;
return (
<div>
<h2>New Message:</h2>
<p>{data.messagePosted.content}</p>
</div>
);
}
export default Messages;
Step 3: Testing delle Subscriptions
Per testare che tutto funzioni correttamente:
- Avvia il server Apollo con
node server.js
. - Assicurati che il client sia in esecuzione e collegato al server.
- Usa il client per inviare una nuova mutazione
postMessage
. Dovresti vedere il nuovo messaggio apparire automaticamente tramite la subscription.
Best Practices
- Gestione degli Errori: Implementa un sistema robusto di gestione degli errori sia nel server che nel client per gestire eventuali disconnessioni o problemi con le subscriptions.
- Scalabilità : Se la tua applicazione cresce, considera l’uso di soluzioni scalabili come Redis PubSub o soluzioni basate su eventi per gestire un elevato numero di subscriptions.
- Sicurezza: Implementa autenticazione e autorizzazione anche per le subscriptions, specialmente in applicazioni dove i dati sensibili sono trasmessi in tempo reale.
Conclusione
Le subscriptions sono una potente funzionalità di GraphQL che permette di costruire applicazioni reattive e in tempo reale. Utilizzando Apollo Server e Apollo Client, puoi implementare facilmente subscriptions nel tuo progetto, fornendo un’esperienza utente migliorata e più interattiva. Seguendo questa guida, dovresti essere in grado di configurare e utilizzare subscriptions in modo efficace nel tuo prossimo progetto.