🚀 Nuova versione beta disponibile! Feedback o problemi? Contattaci

Implementazione di Eventi in Tempo Reale con GraphQL, Node.js ed Express

Codegrind Team•Aug 28 2024

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.