Contexto: por qué esta migración no es solo cambiar una API
Las notificaciones de Exchange Web Services, EWS, han sido durante años una pieza habitual en integraciones con buzones de Exchange: aplicaciones que reaccionan a correo nuevo, cambios de calendario, contactos, tareas o movimientos de elementos. EWS soporta tres patrones de notificación: push, pull y streaming. Ese abanico permitía implementar desde procesos periódicos de reconciliación hasta canales persistentes para recibir cambios casi en tiempo real.
Microsoft Graph propone otro modelo. En lugar de replicar esos patrones uno a uno, utiliza change notifications mediante webhooks y, para escenarios empresariales, integración con Event Hubs. La diferencia es importante: la migración no es 1:1. No basta con sustituir un endpoint EWS por un endpoint Graph y mantener la misma lógica interna.
El cambio exige adoptar una arquitectura más stateless y event-driven, con procesamiento asíncrono, deduplicación, reintentos controlados y consultas de reconciliación. En la práctica, el éxito de la migración depende menos del mapeo de llamadas y más del rediseño del flujo de eventos.
Qué cambia al pasar de EWS a Microsoft Graph
De push, pull y streaming a notificaciones de cambio
En EWS, una aplicación podía elegir entre notificaciones push, pull o streaming. En Microsoft Graph, el patrón principal son las change notifications entregadas a un endpoint webhook. Para organizaciones con mayor volumen o necesidades empresariales, Graph también permite usar Event Hubs como mecanismo de entrega.
La consecuencia directa es que desaparece el equivalente funcional de streaming de EWS. Si una solución dependía de una conexión persistente para recibir eventos, debe replantearse. Las alternativas recomendadas pasan por exponer un endpoint público seguro, enviar eventos a un backend que a su vez use mecanismos push como APNs o FCM cuando aplique, o apoyarse en Event Hubs para desacoplar la ingesta y el procesamiento.
De GetEvents y watermark a delta queries
En EWS, era habitual usar GetEvents y un watermark para recuperar cambios y continuar desde un punto conocido. En Microsoft Graph, ese patrón se sustituye por delta queries.
Las delta queries son esenciales para la reconciliación: permiten revisar el estado real de los recursos y detectar cambios que no se hayan procesado correctamente por retrasos, caídas, throttling o pérdida de notificaciones. En una arquitectura robusta, las notificaciones no deben ser la única fuente de verdad; deben actuar como señal para activar procesamiento, mientras que las delta queries ayudan a confirmar y reconstruir estado.
De eventos específicos a eventos genéricos
EWS ofrecía eventos con semántica más específica, como NewMail. En Graph, el modelo se basa en cambios del tipo created, updated y deleted. Eso implica que ciertos eventos deben inferirse.
Por ejemplo, un correo nuevo puede derivarse de un evento created, pero un movimiento o una copia pueden requerir análisis adicional de propiedades, patrones de cambio e identificadores. En este punto son útiles los immutable IDs, que ayudan a correlacionar movimientos dentro del mismo mailbox. Sin embargo, tienen un límite importante: no resuelven correlación cuando se cruzan boundaries de mailbox o archive.
Tabla comparativa: EWS Notifications frente a Microsoft Graph
| Área | EWS Notifications | Microsoft Graph |
|---|---|---|
| Modelos de entrega | Push, pull y streaming | Change notifications vía webhooks; Event Hubs para escenarios empresariales |
| Arquitectura habitual | Puede mantener estado de conexión o watermark | Stateless, event-driven y orientada a procesamiento asíncrono |
| Reconciliación | GetEvents y watermark |
Delta queries |
| Streaming | Soportado | No hay equivalente directo |
| Semántica de eventos | Eventos más específicos, como NewMail |
created, updated, deleted; algunos casos requieren inferencia |
| Correlación de movimientos | Basada en la lógica EWS y estado de la aplicación | Immutable IDs ayudan dentro del mailbox, no cruzando mailbox/archive |
| Granularidad | Más granular en algunos escenarios legacy | Menor granularidad; ciertas carpetas custom o legacy pueden no funcionar con endpoints específicos |
| Escenarios de alto volumen | Dependientes del diseño EWS | Recomendable cola, deduplicación, worker pool, semáforos, backoff, delta queries y/o Event Hubs |
Por qué importa para arquitecturas Microsoft 365
La migración importa porque las notificaciones suelen estar en el corazón de procesos críticos: archivado, clasificación, sincronización con CRM, alertas operativas, flujos de aprobación o automatizaciones internas. Si se traslada la lógica de forma literal, se corre el riesgo de crear una integración frágil.
El modelo de Graph obliga a separar tres responsabilidades:
- Recepción rápida del evento: el webhook debe responder con rapidez y no ejecutar lógica pesada.
- Procesamiento desacoplado: los eventos deben entrar en una cola o mecanismo equivalente para que un worker los procese.
- Reconciliación periódica o bajo demanda: las delta queries deben usarse para corregir desviaciones y recuperar cambios.
Este diseño es especialmente relevante por el comportamiento de Graph ante webhooks lentos. Si más del 10% de las respuestas tardan más de 10 segundos durante una ventana de 10 minutos, el endpoint puede entrar en estado slow. Si más del 15% supera ese umbral, puede pasar a estado drop. En ese estado, las entregas pueden detenerse hasta 10 minutos y se pueden perder eventos.
Por tanto, el webhook no debería hacer llamadas complejas, consultar múltiples sistemas ni procesar adjuntos en línea. Su función debe ser validar, registrar de forma mínima, encolar y responder.
Diseño recomendado de procesamiento
Endpoint webhook ligero
El endpoint expuesto debe ser público y seguro. Su objetivo es recibir notificaciones de Graph y responder dentro de los tiempos esperados. Cualquier tarea costosa debe delegarse.
Un flujo recomendable sería:
- Recibir la notificación.
- Validar la solicitud según el mecanismo requerido por la integración.
- Persistir un registro mínimo o enviar el mensaje a una cola.
- Responder inmediatamente.
- Procesar el cambio desde workers internos.
Este patrón reduce el riesgo de entrar en estado slow o drop y permite absorber picos sin bloquear la recepción.
Cola, deduplicación y workers
En integraciones de eventos es normal recibir duplicados, eventos fuera de orden o señales que requieran consultar el estado actual. Por eso conviene introducir:
- Cola para desacoplar recepción y procesamiento.
- Deduplicación para evitar reprocesar el mismo cambio.
- Worker pool para paralelizar de forma controlada.
- Semaphore o limitador por mailbox para respetar límites operativos.
- Backoff ante respuestas de throttling o errores transitorios.
- Delta queries para reconciliar estado después de errores, retrasos o caídas.
La fuente verificada destaca un límite relevante de throttling: cuatro conexiones concurrentes por mailbox. En una migración real, este dato debe influir en la concurrencia efectiva. No basta con escalar horizontalmente workers si todos terminan presionando el mismo buzón. La escala debe estar gobernada por particionamiento, límites por mailbox y reintentos con backoff.
Rich notifications para reducir llamadas posteriores
Las rich notifications pueden reducir llamadas posteriores a Microsoft Graph porque incluyen más información en la notificación. Esto no elimina la necesidad de reconciliación, pero sí puede disminuir el número de consultas adicionales cuando la aplicación solo necesita ciertos datos para decidir qué hacer.
La decisión de usarlas debe evaluarse desde seguridad, minimización de datos y necesidades funcionales. Si el evento contiene suficiente contexto para enrutar o clasificar, se reduce latencia y presión sobre la API. Si la aplicación requiere estado definitivo o propiedades no incluidas, seguirá siendo necesario consultar Graph.
Qué revisar antes de adoptarlo
Recursos y carpetas soportadas
Microsoft Graph tiene menor granularidad que EWS en algunos escenarios. Además, carpetas custom o carpetas legacy pueden no funcionar con determinados endpoints como messages, contacts, events o to do.
Antes de migrar, conviene inventariar:
- Qué tipos de elementos se monitorizan.
- En qué carpetas viven.
- Si existen carpetas personalizadas o heredadas.
- Qué endpoints de Graph se usarán para cada caso.
- Qué eventos de negocio dependen de semántica específica de EWS.
Este análisis evita descubrir tarde que una parte del modelo funcional no encaja con Graph tal como está diseñado.
Semántica de eventos de negocio
Si una aplicación depende de eventos como NewMail, movimientos, copias o eliminaciones específicas, hay que rediseñar la inferencia. Graph entrega eventos created, updated y deleted; la aplicación debe interpretar el significado de negocio a partir de propiedades, patrones e immutableId cuando sea aplicable.
Los immutable IDs son útiles para correlacionar movimientos dentro del mailbox, pero no deben tratarse como solución universal. No permiten correlacionar de forma fiable cuando el elemento cruza boundaries de mailbox o archive.
Estrategia de pérdida y reconciliación
Toda solución debe asumir que una notificación puede llegar tarde, duplicada o no llegar. Esta no es una anomalía exclusiva de Graph; es una premisa sana en arquitecturas distribuidas. La diferencia es que Graph documenta estados operativos de webhooks que pueden provocar pausas o pérdida de eventos si el endpoint no responde a tiempo.
Por ello, antes de adoptar el nuevo modelo hay que definir:
- Frecuencia y alcance de delta queries.
- Política de reintentos y backoff.
- Ventanas de reconciliación tras incidentes.
- Métricas de latencia del webhook.
- Alertas por errores, colas acumuladas y throttling.
- Límite de concurrencia por mailbox.
Plan práctico de migración
Una migración prudente debería comenzar con un piloto acotado. Selecciona un conjunto reducido de buzones y eventos, implementa las suscripciones de Graph y procesa las notificaciones en paralelo con la lógica EWS existente. Durante ese periodo, compara resultados: eventos recibidos, cambios detectados por delta queries, duplicados, retrasos y divergencias.
Después, clasifica las diferencias. Algunas serán esperables por el cambio de modelo; otras indicarán problemas de inferencia o de cobertura funcional. Ajusta la deduplicación, el uso de immutable IDs, las reglas para moves y copies, y la frecuencia de reconciliación.
Cuando el comportamiento sea estable, amplía por lotes. Evita una migración masiva sin límites de concurrencia, especialmente si muchos workers procesan buzones activos. El control por mailbox, la cola y el backoff son parte del diseño, no optimizaciones opcionales.
Conclusión práctica
Migrar notificaciones EWS a Microsoft Graph no es una conversión directa de API. Es una modernización del patrón de integración: de modelos push, pull y streaming hacia change notifications, webhooks, Event Hubs y delta queries.
La recomendación práctica es diseñar desde el principio para eventos imperfectos: webhook rápido, procesamiento desacoplado, deduplicación, límites por mailbox, backoff y reconciliación con delta queries. Usa rich notifications cuando reduzcan llamadas posteriores, pero no las conviertas en la única fuente de verdad. Revisa también la granularidad de Graph y la compatibilidad de carpetas custom o legacy antes de comprometer el diseño.
Si la aplicación dependía de streaming EWS, asume que no existe equivalente directo en Graph y elige una alternativa: endpoint público seguro, backend push con APNs/FCM cuando aplique o Event Hubs para escenarios empresariales. Con este enfoque, la migración no solo sustituye EWS: prepara la integración para operar de forma más resiliente en Microsoft 365.