Concepto clave
Las suscripciones GraphQL son un mecanismo que permite a los clientes recibir actualizaciones en tiempo real cuando ocurren eventos especificos en el servidor. A diferencia de las queries (consultas) y mutations (mutaciones), que siguen el modelo request-response tradicional, las suscripciones mantienen una conexion persistente mediante WebSockets.
Imagina una red social como Twitter: cuando alguien que sigues publica un nuevo tweet, no tienes que recargar la pagina constantemente para verlo. En su lugar, la aplicacion se suscribe a las actualizaciones de tu feed, y el servidor empuja la nueva informacion tan pronto como esta disponible. Esto es exactamente lo que hacen las suscripciones GraphQL: transforman tu API de un sistema de "preguntar y esperar" a uno de "escuchar y recibir".
Como funciona en la practica
Para implementar suscripciones en una API GraphQL con Apollo Server y Next.js, necesitas configurar tanto el servidor como el cliente. En el servidor, defines un resolver de suscripcion que utiliza PubSub (publicador-suscriptor) para manejar eventos. En el cliente, configuras Apollo Client para usar WebSockets.
Paso a paso:
- Instala las dependencias necesarias:
graphql-subscriptionsysubscriptions-transport-wsen el servidor. - Configura Apollo Server para aceptar conexiones WebSockets, ademas de HTTP.
- Define el tipo de suscripcion en tu schema GraphQL, por ejemplo:
type Subscription { newNotification: Notification }. - Crea un resolver de suscripcion que utilice
PubSub.asyncIteratorpara escuchar eventos. - En las mutations relevantes (como crear una notificacion), publica el evento usando
PubSub.publish. - En el cliente Next.js, configura Apollo Client con un link de WebSockets para suscribirse a los datos.
Caso de estudio
Vamos a aplicar esto a nuestro proyecto de red social. Supongamos que queremos notificar a los usuarios cuando reciben un nuevo mensaje privado. Primero, definimos el schema:
type Message {
id: ID!
content: String!
sender: User!
receiver: User!
createdAt: String!
}
type Subscription {
newMessage(receiverId: ID!): Message
}Luego, en el servidor, implementamos el resolver de suscripcion:
import { PubSub } from 'graphql-subscriptions';
const pubsub = new PubSub();
const resolvers = {
Subscription: {
newMessage: {
subscribe: (_, { receiverId }) => {
return pubsub.asyncIterator([`NEW_MESSAGE_${receiverId}`]);
}
}
},
Mutation: {
sendMessage: async (_, { content, receiverId }) => {
const message = await createMessage(content, receiverId);
pubsub.publish(`NEW_MESSAGE_${receiverId}`, { newMessage: message });
return message;
}
}
};En el cliente, nos suscribimos en un componente React:
import { useSubscription } from '@apollo/client';
import { NEW_MESSAGE_SUBSCRIPTION } from '../graphql/subscriptions';
function MessageNotification({ userId }) {
const { data } = useSubscription(NEW_MESSAGE_SUBSCRIPTION, {
variables: { receiverId: userId }
});
if (data) {
return Nuevo mensaje de {data.newMessage.sender.name};
}
return null;
}Errores comunes
- Olvidar configurar WebSockets en Apollo Server: Sin esto, las suscripciones no funcionaran. Asegurate de usar
ApolloServerconsubscriptions: { path: '/graphql' }en Next.js API routes. - No limpiar suscripciones en el cliente: En React, si no limpias las suscripciones al desmontar el componente, pueden causar fugas de memoria. Usa
useEffectcon una funcion de limpieza. - Publicar eventos sin datos validos: Asegurate de que los datos publicados coincidan con el tipo esperado en la suscripcion, o GraphQL lanzara errores.
- Ignorar la escalabilidad:
PubSuben memoria no escala en produccion. Para aplicaciones reales, usa adaptadores como Redis. - Confundir suscripciones con polling: Las suscripciones son para tiempo real; no las uses para datos que cambian raramente, donde una query periodica es mas simple.
Checklist de dominio
- He configurado Apollo Server en Next.js para soportar suscripciones via WebSockets.
- He definido al menos un tipo de suscripcion en mi schema GraphQL con parametros si es necesario.
- He implementado un resolver de suscripcion que usa
PubSub.asyncIteratorpara escuchar eventos especificos. - He modificado una mutation para publicar eventos usando
PubSub.publishcuando ocurre un cambio relevante. - He configurado Apollo Client en el frontend con un link de WebSockets para manejar suscripciones.
- He usado
useSubscriptionen un componente React para suscribirme y mostrar datos en tiempo real. - He probado que las suscripciones funcionan enviando datos y viendo las actualizaciones automaticas en el cliente.
Implementar Suscripciones para Notificaciones de Likes en una Red Social
En este ejercicio, vas a agregar suscripciones GraphQL a tu API para notificar a los usuarios cuando alguien da like a uno de sus posts. Sigue estos pasos:
- En tu proyecto Next.js con Apollo Server, asegurate de tener configurado WebSockets. Si no, actualiza tu configuracion en
/pages/api/graphql.jspara incluirsubscriptions: { path: '/graphql' }en el constructor deApolloServer. - Agrega un tipo de suscripcion a tu schema GraphQL:
type Subscription { newLike(postId: ID!): Like }, dondeLikees un tipo existente con campos comoid,user, ypost. - Crea un resolver de suscripcion en tu archivo de resolvers. Usa
PubSubdegraphql-subscriptionspara suscribirte a eventos con el patronNEW_LIKE_${postId}. - Modifica la mutation
addLikepara publicar un evento cuando se agrega un like. Asegurate de incluir elpostIden la publicacion. - En el frontend, configura Apollo Client para usar suscripciones. Instala
subscriptions-transport-wsy crea un WebSocket link que apunte a tu servidor (ej.,ws://localhost:3000/api/graphql). - En un componente React, usa
useSubscriptionpara suscribirte anewLikecon unpostIdespecifico. Muestra una notificacion cuando llegue un nuevo like. - Prueba la funcionalidad: ejecuta tu aplicacion, da like a un post desde otra sesion, y verifica que la notificacion aparezca en tiempo real.
- Recuerda inicializar PubSub como una instancia compartida en tus resolvers para evitar problemas de scope.
- En el cliente, asegurate de que el WebSocket link este correctamente integrado en la configuracion de Apollo Client usando split para manejar tanto queries como suscripciones.
- Si no ves las actualizaciones, revisa la consola del navegador y del servidor para errores de conexion WebSocket o de schema.
Evalua tu comprension
Completa el quiz interactivo de arriba para ganar XP.