Saltar al contenido

Lección 14 de 20 · Lectura y práctica

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

Concepto claveLas 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.

Del concepto a la práctica

Taller de esta lección

Un chat mínimo debe preservar orden, autor y sala. La suscripción no sustituye la mutación: la mutación valida que la persona pertenezca a la sala, guarda el mensaje y publica un evento con una secuencia comprobable.

Ejemplo resuelto

Sala s1 tiene a u1 y u2. u1 envía m1: "Hola" y u2 envía m2: "Respuesta". Ambos suscriptores de s1 reciben m1 seguido de m2; un suscriptor de s2 no recibe ninguno.

  1. Define Message con id, roomId, authorId, text y createdAt.

  2. Rechaza mensajes vacíos o autores que no pertenezcan a la sala.

  3. Publica el evento con roomId después de guardar.

  4. Filtra la suscripción por sala y limpia al desmontar el cliente.

Error frecuente: publicar antes de confirmar la inserción. Corrección: guarda primero y publica solo el registro persistido.

Pruébalo

Envía un texto vacío desde u1 y un texto válido desde u2.

Comprueba tu resultado

En un almacén nuevo del ejercicio solo existe m2; ambos suscriptores de s1 reciben m2 una vez y la sala s2 permanece sin mensajes.

Fixture limpio y secuencia

El ejemplo resuelto tiene m1 y m2; la prueba de texto vacío empieza desde un almacén nuevo para poder esperar solo m2. Define una secuencia de sala asignada atómicamente al guardar: los clientes ordenan por ella y deduplican por id. Dos publicaciones concurrentes pueden llegar en distinto orden sin esa política. Valida pertenencia en creación y suscripción, no solo roomId. El evento contiene el registro ya guardado y se envuelve bajo messageAdded si ese es el nombre del campo Subscription. Una escritura seguida de publicación en RAM puede perder un evento al caerse el proceso: la notificación duradera requiere otro mecanismo, por ejemplo outbox.

Navegador, API y base de datos conectados por solicitudes, consultas y respuestas en sentidos opuestos.
CursaloMapa de práctica
Del navegador a los datos

El navegador envía una solicitud a la API. El servidor valida la operación y consulta los datos; después devuelve una respuesta que el navegador puede mostrar. La base de datos se comunica con el servidor y no directamente con el navegador.

Ver la infografía en tamaño completo ↗
Fuentes para profundizar

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.

Sigue con GraphQL Profesional con Next.js y Apollo Server: APIs Tipadas y Suscripciones

Esta lección forma parte de un curso de Cursalo. Revisa su programa y elige entre la compra individual o el acceso a toda la escuela.

Si ya tenías acceso a este curso, entra con tu cuenta: tus derechos y tu progreso se conservan. No necesitas comprarlo de nuevo.

01 / ELEGIR UNA RUTA

El próximo paso

Aprende IA mientras construyes algo que sí necesitas.

Empieza por el curso inicial o explora el catálogo para encontrar una práctica alineada con tu trabajo.