Implementazione di Eventi in Tempo Reale con GraphQL, Node.js ed Express
Implementare eventi in tempo reale nelle API GraphQL con Node.js ed Express consente di costruire applicazioni interattive e reattive, che rispondono immediatamente ai cambiamenti nei dati. Utilizzando le subscription di GraphQL e tecnologie come WebSocket, è possibile inviare aggiornamenti in tempo reale ai client quando si verificano determinati eventi. In questa guida, esploreremo come configurare e implementare eventi in tempo reale in un’applicazione GraphQL basata su Node.js ed Express.
1. Prerequisiti
Per seguire questa guida, dovresti avere:
- Familiarità con Node.js e Express.
- Una conoscenza di base di GraphQL.
- Ambiente Node.js configurato.
2. Configurazione di Base di GraphQL con Node.js ed Express
2.1. Installare le Dipendenze Necessarie
Per iniziare, crea un nuovo progetto Node.js e installa le dipendenze necessarie:
mkdir graphql-realtime
cd graphql-realtime
npm init -y
npm install express apollo-server-express graphql graphql-subscriptions ws
2.2. Configurare Express e Apollo Server
Configura Express e Apollo Server per servire l’API GraphQL:
const express = require('express');
const { ApolloServer } = require('apollo-server-express');
const { makeExecutableSchema } = require('@graphql-tools/schema');
const { execute, subscribe } = require('graphql');
const { SubscriptionServer } = require('subscriptions-transport-ws');
const { createServer } = require('http');
const { PubSub } = require('graphql-subscriptions');
const typeDefs = /* GraphQL schema */;
const resolvers = /* GraphQL resolvers */;
const app = express();
const pubsub = new PubSub();
const schema = makeExecutableSchema({ typeDefs, resolvers });
const server = new ApolloServer({ schema });
server.applyMiddleware({ app });
const httpServer = createServer(app);
httpServer.listen(4000, () => {
new SubscriptionServer(
{
execute,
subscribe,
schema,
},
{
server: httpServer,
path: '/graphql',
}
);
console.log(`Server pronto su http://localhost:4000${server.graphqlPath}`);
});
2.3. Definire il Tipo e la Subscription nel Schema
Per supportare eventi in tempo reale, dobbiamo definire una subscription nel nostro schema GraphQL.
const typeDefs = `
type Message {
id: ID!
content: String!
}
type Query {
messages: [Message!]!
}
type Mutation {
postMessage(content: String!): Message!
}
type Subscription {
messagePosted: Message!
}
`;
const resolvers = {
Query: {
messages: () => messages,
},
Mutation: {
postMessage: (parent, { content }) => {
const message = { id: messages.length + 1, content };
messages.push(message);
pubsub.publish("MESSAGE_POSTED", { messagePosted: message });
return message;
},
},
Subscription: {
messagePosted: {
subscribe: () => pubsub.asyncIterator(["MESSAGE_POSTED"]),
},
},
};
const messages = [];
3. Implementazione di Eventi in Tempo Reale
3.1. Subscription con WebSocket
Nell’esempio sopra, abbiamo utilizzato graphql-subscriptions
per implementare eventi in tempo reale. La subscription messagePosted
consente ai client di ricevere notifiche in tempo reale ogni volta che un nuovo messaggio viene pubblicato.
3.2. Testare le Subscription
Puoi testare le subscription utilizzando GraphQL Playground o Apollo Studio Explorer. Quando un client si iscrive a messagePosted
, riceverà automaticamente un aggiornamento ogni volta che viene postato un nuovo messaggio.
Esempio di Subscription Client-Side
subscription {
messagePosted {
id
content
}
}
Esempio di Mutazione Client-Side
mutation {
postMessage(content: "Hello, world!") {
id
content
}
}
3.3. Gestire Più Eventi
Puoi estendere questa configurazione per gestire più eventi. Basta aggiungere più subscription nel tuo schema e utilizzare pubsub.publish
per notificare i client di diversi eventi.
Esempio di Subscription Multipla
type Subscription {
messagePosted: Message!
userJoined: User!
}
4. Best Practices per Gestione degli Eventi in Tempo Reale
4.1. Scalabilità con Redis
Quando si gestiscono molti eventi in tempo reale, l’uso di un Redis Pub/Sub può aiutare a scalare l’applicazione distribuendo gli eventi su più istanze del server.
4.2. Gestione delle Connessioni
Assicurati di gestire le connessioni WebSocket in modo efficiente per evitare problemi di sovraccarico, specialmente in applicazioni con molti utenti.
4.3. Sicurezza
Implementa l’autenticazione e l’autorizzazione per le subscription per evitare accessi non autorizzati ai dati in tempo reale.
5. Esempio Completo
Ecco un esempio completo di un’applicazione che utilizza GraphQL, Node.js ed Express per gestire eventi in tempo reale:
const express = require("express");
const { ApolloServer } = require("apollo-server-express");
const { makeExecutableSchema } = require("@graphql-tools/schema");
const { execute, subscribe } = require("graphql");
const { SubscriptionServer } = require("subscriptions-transport-ws");
const { createServer } = require("http");
const { PubSub } = require("graphql-subscriptions");
const typeDefs = `
type Message {
id: ID!
content: String!
}
type Query {
messages: [Message!]!
}
type Mutation {
postMessage(content: String!): Message!
}
type Subscription {
messagePosted: Message!
}
`;
const messages = [];
const pubsub = new PubSub();
const resolvers = {
Query: {
messages: () => messages,
},
Mutation: {
postMessage: (parent, { content }) => {
const message = { id: messages.length + 1, content };
messages.push(message);
pubsub.publish("MESSAGE_POSTED", { messagePosted: message });
return message;
},
},
Subscription: {
messagePosted: {
subscribe: () => pubsub.asyncIterator(["MESSAGE_POSTED"]),
},
},
};
const app = express();
const schema = makeExecutableSchema({ typeDefs, resolvers });
const server = new ApolloServer({ schema });
server.applyMiddleware({ app });
const httpServer = createServer(app);
httpServer.listen(4000, () => {
new SubscriptionServer(
{
execute,
subscribe,
schema,
},
{
server: httpServer,
path: "/graphql",
}
);
console.log(`Server pronto su http://localhost:4000${server.graphqlPath}`);
});
Conclusione
L’implementazione di eventi in tempo reale con GraphQL, Node.js ed Express consente di costruire applicazioni moderne e interattive. Utilizzando subscription e WebSocket, puoi fornire aggiornamenti istantanei ai tuoi utenti, migliorando significativamente l’esperienza utente. Seguendo le best practices e l’esempio fornito in questa guida, sarai in grado di implementare eventi in tempo reale nelle tue API GraphQL in modo efficace e scalabile.