Lección 11 de 20 · Lectura y práctica
Configurar Suscripciones con Apollo Server y WebSockets
Concepto claveLas suscripciones GraphQL son una característica que permite a los clientes recibir actualizaciones en tiempo real cuando ocurren cambios específicos en los datos del servidor. A diferencia de las consultas y.
Del concepto a la práctica
Taller de esta lección
Configurar una suscripción implica coordinar dos transportes: las consultas y mutaciones viajan por la ruta habitual, mientras la suscripción mantiene un canal persistente. La prueba principal no es ver una pantalla, sino demostrar que un evento publicado llega a una operación suscrita y que una conexión cerrada deja de recibirlo.
Ejemplo resuelto
Evento local ROOM_RENAMED con { roomId: "r1", name: "Norte 2" }. La suscripción solicita roomRenamed { roomId name } y recibe exactamente ese objeto cuando una mutación publica el evento.
Declara el tipo
Subscriptiony su campo de evento.Configura el servidor WebSocket en el mismo entorno autorizado.
Conecta una operación suscrita y conserva su cleanup.
Ejecuta la mutación publicadora y observa un único mensaje.
Error frecuente: publicar antes de que el suscriptor esté conectado. Corrección: espera que la operación de suscripción esté registrada en el servidor y después dispara la mutación; connection_ack por sí solo no demuestra ese registro.
Pruébalo
Abre dos suscriptores, publica un renombrado y cierra uno antes del segundo evento.
Comprueba tu resultado
Ambos reciben el primer evento; solo el suscriptor activo recibe el segundo y el proceso no conserva listeners del cerrado.
Transportes y payload del laboratorio
Apollo Server no incluye automáticamente suscripciones al abrir una ruta HTTP de Next.js. Para la práctica de WebSocket utiliza un servidor Node duradero separado y graphql-ws, con el protocolo graphql-transport-ws. No mezcles el paquete retirado subscriptions-transport-ws. Un esquema común incluye Query.health, Mutation.renameRoom y Subscription.roomRenamed:RoomEvent!, con RoomEvent.roomId y name. El resolver subscribe devuelve un AsyncIterator; con graphql-subscriptions actual puedes usar pubsub.asyncIterableIterator('ROOM_RENAMED'). Publica {roomRenamed: {roomId: 'r1', name: 'Norte 2'}} para que el resolver de campo encuentre el objeto correcto.
El host Node configura WebSocketServer, comparte el esquema ejecutable y llama useServer desde graphql-ws/use/ws. Conserva el dispose de servidor y el cleanup de cada operación cliente. La prueba registra que subscribe ha creado el iterador antes de publicar; cerrar la operación debe finalizarlo. Un PubSub en RAM sirve para una instancia del laboratorio, sin prometer durabilidad ni entregas entre varios procesos.

Mapa de prácticaEl 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 GraphQL son una característica que permite a los clientes recibir actualizaciones en tiempo real cuando ocurren cambios específicos en los datos del servidor. A diferencia de las consultas y mutaciones tradicionales que siguen un modelo request-response, las suscripciones mantienen una conexión persistente usando WebSockets.
Imagina que estás en una sala de chat: en lugar de preguntar constantemente "¿hay mensajes nuevos?" (como haría una consulta tradicional), te suscribes al canal y recibes notificaciones automáticamente cuando alguien escribe. Apollo Server implementa esto mediante el protocolo GraphQL over WebSocket, que establece un canal bidireccional entre cliente y servidor.
Cómo funciona en la práctica
Para configurar suscripciones en Apollo Server con Next.js, necesitas tres componentes principales:
- Un servidor WebSocket que maneje las conexiones persistentes
- Un PubSub (publicador-suscriptor) que gestione los eventos
- Resolvers de suscripción que definan qué datos enviar
Paso a paso:
// 1. Configurar Apollo Server con soporte WebSocket
import { ApolloServer } from 'apollo-server-micro';
import { WebSocketServer } from 'ws';
import { useServer } from 'graphql-ws/lib/use/ws';
const apolloServer = new ApolloServer({
typeDefs,
resolvers,
subscriptions: {
path: '/api/graphql',
},
});
// 2. Crear instancia de WebSocketServer
const wsServer = new WebSocketServer({
server: httpServer,
path: '/api/graphql',
});
// 3. Conectar WebSocket con Apollo
useServer({ schema }, wsServer);Caso de estudio
Implementemos un sistema de notificaciones en tiempo real para una aplicación de gestión de proyectos. Cuando un usuario asigna una nueva tarea, todos los miembros del equipo reciben una notificación inmediata.
| Componente | Implementación |
|---|---|
| TypeDefs | |
| PubSub | |
| Resolver de mutación | |
| Resolver de suscripción | |
El filtro (withFilter) es crucial para evitar que los usuarios reciban notificaciones de proyectos a los que no pertenecen.
Errores comunes
- Olvidar configurar CORS para WebSockets: Los navegadores bloquean conexiones WebSocket desde dominios no autorizados. Configura CORS tanto para HTTP como para WebSocket.
- No manejar reconexiones: Las conexiones WebSocket pueden fallar. Implementa lógica de reconexión en el cliente con backoff exponencial.
- Filtrar mal los eventos: Sin filtros adecuados, los usuarios reciben datos que no les corresponden, comprometiendo seguridad y rendimiento.
- Ignorar el escalado horizontal: PubSub en memoria no funciona con múltiples instancias del servidor. Para producción, usa Redis PubSub.
- No limpiar suscripciones: En React/Next.js, debes limpiar las suscripciones en useEffect para evitar memory leaks.
Checklist de dominio
- ¿Puedes configurar Apollo Server con soporte WebSocket en Next.js?
- ¿Sabes implementar un resolver de suscripción con filtros?
- ¿Entiendes la diferencia entre pubsub.publish() y pubsub.asyncIterator()?
- ¿Puedes conectar un cliente Apollo a suscripciones desde React?
- ¿Sabes manejar errores de conexión WebSocket?
- ¿Puedes escalar suscripciones usando Redis en producción?
- ¿Entiendes cuándo usar suscripciones vs polling vs Server-Sent Events?
Implementar un chat en tiempo real con GraphQL Subscriptions
Crea un sistema de chat básico donde los usuarios puedan enviar mensajes y ver los mensajes de otros en tiempo real.
- Configura Apollo Server en Next.js con soporte para WebSockets
- Define los tipos GraphQL necesarios:
- Mensaje: id, contenido, usuario, timestamp
- Mutation: enviarMensaje(contenido: String!, usuario: String!): Mensaje
- Subscription: mensajeEnviado: Mensaje
- Implementa el resolver para la mutación enviarMensaje que publique el evento
- Implementa el resolver para la suscripción mensajeEnviado
- Crea un componente React que:
- Muestre los mensajes existentes
- Permita enviar nuevos mensajes
- Se suscriba para recibir mensajes nuevos en tiempo real
- Prueba abriendo dos pestañas del navegador y enviando mensajes desde ambas
Pistas
- Usa graphql-ws para el servidor WebSocket
- Recuerda limpiar la suscripción en el cleanup de useEffect
- El timestamp puede generarse con new Date().toISOString()
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.