Saltar al contenido

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

Agregar Suscripciones para Notificaciones y Actualizaciones

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

Del concepto a la práctica

Taller de esta lección

En el proyecto integrador, una notificación debe representar una consecuencia de negocio, no cada cambio interno. Selecciona eventos que el cliente pueda usar: comentario nuevo para el autor de una publicación y actualización de una publicación para quienes la siguen, con filtros explícitos.

Ejemplo resuelto

c1 comenta p1, cuyo autor es u1. Se publica COMMENT_ADDED con recipientId: "u1"; u1 recibe la notificación y u2, que no es destinatario, no. El payload incluye commentId y postId para actualizar la vista.

  1. Obtén el destinatario desde la publicación persistida.

  2. Guarda la notificación con un identificador único.

  3. Publica después de confirmar la escritura.

  4. Filtra por identidad y, si aplica, por publicación seguida.

Error frecuente: enviar el evento a todos los clientes conectados y ocultarlo en la interfaz. Corrección: filtra en el servidor y prueba un usuario ajeno.

Pruébalo

Haz que u2 comente p1 mientras están conectados u1 y u3.

Comprueba tu resultado

Solo u1 recibe COMMENT_ADDED; el payload referencia c1 y p1, y la notificación queda almacenada una sola vez.

Una notificación única no nace del transporte

Que una mutación publique una vez no garantiza una única entrega o almacenamiento. Guarda una clave de evento de negocio única y un outbox en la misma transacción que el comentario; un worker puede reintentar publicación y el receptor deduplica por notification.id. En el fixture c1/p1/recipient:u1 siempre conserva n1. El segundo usuario comentarista y u3 no reciben datos de u1. Para una suscripción de publicaciones seguidas comprueba además pertenencia y visibilidad por evento. Un PubSub local sin outbox no demuestra esta durabilidad.

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 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:

  1. Instala las dependencias necesarias: graphql-subscriptions y subscriptions-transport-ws en el servidor.
  2. Configura Apollo Server para aceptar conexiones WebSockets, ademas de HTTP.
  3. Define el tipo de suscripcion en tu schema GraphQL, por ejemplo: type Subscription { newNotification: Notification }.
  4. Crea un resolver de suscripcion que utilice PubSub.asyncIterator para escuchar eventos.
  5. En las mutations relevantes (como crear una notificacion), publica el evento usando PubSub.publish.
  6. 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 ApolloServer con subscriptions: { 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 useEffect con 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: PubSub en 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

  1. He configurado Apollo Server en Next.js para soportar suscripciones via WebSockets.
  2. He definido al menos un tipo de suscripcion en mi schema GraphQL con parametros si es necesario.
  3. He implementado un resolver de suscripcion que usa PubSub.asyncIterator para escuchar eventos especificos.
  4. He modificado una mutation para publicar eventos usando PubSub.publish cuando ocurre un cambio relevante.
  5. He configurado Apollo Client en el frontend con un link de WebSockets para manejar suscripciones.
  6. He usado useSubscription en un componente React para suscribirme y mostrar datos en tiempo real.
  7. 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:

  1. En tu proyecto Next.js con Apollo Server, asegurate de tener configurado WebSockets. Si no, actualiza tu configuracion en /pages/api/graphql.js para incluir subscriptions: { path: '/graphql' } en el constructor de ApolloServer.
  2. Agrega un tipo de suscripcion a tu schema GraphQL: type Subscription { newLike(postId: ID!): Like }, donde Like es un tipo existente con campos como id, user, y post.
  3. Crea un resolver de suscripcion en tu archivo de resolvers. Usa PubSub de graphql-subscriptions para suscribirte a eventos con el patron NEW_LIKE_${postId}.
  4. Modifica la mutation addLike para publicar un evento cuando se agrega un like. Asegurate de incluir el postId en la publicacion.
  5. En el frontend, configura Apollo Client para usar suscripciones. Instala subscriptions-transport-ws y crea un WebSocket link que apunte a tu servidor (ej., ws://localhost:3000/api/graphql).
  6. En un componente React, usa useSubscription para suscribirte a newLike con un postId especifico. Muestra una notificacion cuando llegue un nuevo like.
  7. Prueba la funcionalidad: ejecuta tu aplicacion, da like a un post desde otra sesion, y verifica que la notificacion aparezca en tiempo real.
Pistas
  • 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.

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.