Práctica: Crear un Chat en Tiempo Real con Suscripciones

Lectura
30 min~4 min lectura

Concepto clave

Las suscripciones en GraphQL permiten que los clientes reciban actualizaciones en tiempo real cuando ocurren cambios en los datos del servidor. A diferencia de las queries y mutations tradicionales que siguen un modelo request-response, las suscripciones mantienen una conexión persistente usando WebSockets o Server-Sent Events.

Imagina un chat grupal donde cada nuevo mensaje aparece automáticamente en tu pantalla sin tener que refrescar la página. Eso es exactamente lo que logran las suscripciones: notificaciones push desde el servidor hacia los clientes suscritos. En GraphQL, esto se implementa mediante el tipo Subscription en el schema, resolvers especiales, y un transporte como WebSockets con Apollo Server.

Cómo funciona en la práctica

Para implementar suscripciones en tiempo real con Apollo Server y Next.js, sigue estos pasos:

  1. Configura Apollo Server con soporte para suscripciones usando graphql-ws o subscriptions-transport-ws.
  2. Define un tipo Subscription en tu schema GraphQL, por ejemplo: type Subscription { newMessage: Message }.
  3. Crea un resolver de suscripción que use PubSub de Apollo para publicar y suscribirse a eventos.
  4. En el cliente, configura Apollo Client con un WebSocket link para manejar las suscripciones.
  5. Usa el hook useSubscription de Apollo Client en componentes React para recibir datos en tiempo real.

Ejemplo básico de un resolver de suscripción:

const resolvers = {
  Subscription: {
    newMessage: {
      subscribe: () => pubSub.asyncIterator(['NEW_MESSAGE'])
    }
  }
};

Caso de estudio

Vamos a construir un chat en tiempo real para un equipo de desarrollo. Cada mensaje incluye el contenido, el autor, y la marca de tiempo. Usaremos una base de datos en memoria para simplicidad, pero en producción podrías usar PostgreSQL o MongoDB.

CampoTipoDescripción
idIDIdentificador único del mensaje
contentStringTexto del mensaje
authorStringNombre del usuario
timestampStringFecha y hora en ISO format

Cuando un usuario envía un mensaje mediante una mutation, se publica un evento NEW_MESSAGE, y todos los clientes suscritos reciben el nuevo mensaje automáticamente. Esto elimina la necesidad de polling y mejora la experiencia del usuario.

En aplicaciones de chat, las suscripciones reducen la latencia a menos de 100ms, comparado con varios segundos en polling tradicional.

Errores comunes

  • No configurar correctamente el transporte WebSocket: Asegúrate de que Apollo Server esté configurado con el middleware adecuado y que el cliente use el mismo protocolo (ws:// o wss://).
  • Olvidar limpiar suscripciones en React: Siempre usa useEffect con una función de cleanup para evitar memory leaks cuando el componente se desmonta.
  • No manejar reconexiones: Implementa lógica de reintento en el cliente para casos de desconexión de red.
  • Publicar eventos sin validación: Valida los datos en la mutation antes de publicar el evento para evitar inconsistencia.
  • Ignorar escalabilidad: Para muchas conexiones simultáneas, considera usar Redis PubSub en lugar de la implementación en memoria.

Checklist de dominio

  • Puedo explicar la diferencia entre queries, mutations, y suscripciones en GraphQL.
  • He configurado Apollo Server con soporte para suscripciones usando WebSockets.
  • He definido un tipo Subscription en mi schema GraphQL y creado resolvers correspondientes.
  • He implementado un cliente Apollo en Next.js que se suscribe a eventos en tiempo real.
  • Puedo manejar errores y reconexiones en suscripciones del lado del cliente.
  • He probado el flujo completo enviando y recibiendo datos en tiempo real.
  • Entiendo cuándo usar suscripciones versus polling o queries periódicas.

Implementar un chat en tiempo real con GraphQL subscriptions

En este ejercicio, crearás un chat en tiempo real usando GraphQL subscriptions con Apollo Server y Next.js. Sigue estos pasos:

  1. Configura un proyecto Next.js con Apollo Server en el lado del servidor (usando API routes).
  2. Define un schema GraphQL que incluya tipos para Message y Subscription, y una mutation para enviar mensajes.
  3. Implementa resolvers para la mutation (que publique un evento) y la suscripción (que escuche el evento).
  4. Crea una página en Next.js con un formulario para enviar mensajes y una lista que muestre los mensajes en tiempo real usando useSubscription.
  5. Prueba la aplicación abriendo múltiples pestañas del navegador y verificando que los mensajes aparezcan en todas simultáneamente.

Requisitos técnicos:

  • Usa graphql-ws para el transporte WebSocket en Apollo Server.
  • Almacena los mensajes en un array en memoria del servidor (para simplicidad).
  • Asegúrate de que la suscripción se limpie correctamente al desmontar el componente React.
Pistas
  • Recuerda instalar los paquetes necesarios: graphql-ws, @apollo/client, y graphql.
  • En el resolver de la mutation, usa pubSub.publish('NEW_MESSAGE', { newMessage: message }) después de agregar el mensaje al array.
  • En el cliente, configura un WebSocketLink junto con el HttpLink en Apollo Client usando split para manejar suscripciones y queries/mutations por separado.

Evalua tu comprension

Completa el quiz interactivo de arriba para ganar XP.