Arquitectura orientada a eventos vs. request-response — ¿qué cambia en cómo diseñas un sistema?
El modelo request-response acopla servicios mediante llamadas directas y disponibilidad compartida; la arquitectura orientada a eventos los acopla solo a través de la forma de los eventos, cambiando consistencia inmediata por resiliencia y escalado independiente.
APRENDE HACIENDOPon a prueba tu intuición3 pasos
Arquitectura orientada a eventos vs. request-response — ¿qué cambia en cómo diseñas un sistema?
Usa los ejemplos y la explicación de la lección para comprobar tu idea.
Reflexión personal. No se envía a ningún servicio de IA.Request-response y orientado a eventos son dos respuestas distintas a la misma pregunta: cómo le dice un servicio a otra parte del sistema qué hacer, o qué acaba de pasar. La elección no es cosmética — cambia el acoplamiento, el comportamiento ante fallos, las garantías de consistencia y qué tan difícil será depurar el sistema dentro de seis meses.
#Request-response: directo, síncrono, fuertemente acoplado
En un diseño request-response, quien llama envía una solicitud a un servicio específico y se bloquea hasta recibir una respuesta. Quien llama sabe exactamente con quién habla (una dirección, un hostname, un nombre de servicio), y ambos lados deben estar disponibles y saludables en el mismo instante para que la llamada funcione. Si encadenas suficientes llamadas de este tipo —el API gateway llama al servicio de órdenes, que llama a inventario, que llama a pagos— obtienes una cadena de llamadas síncrona: la latencia total es la suma de cada salto, y la disponibilidad de toda la cadena es el producto de la disponibilidad de cada servicio individual. Un tropiezo tres servicios más adentro se manifiesta de inmediato en quien hizo la llamada original, como un timeout o un 5xx.
Esa inmediatez es también la mayor ventaja de request-response: quien llama obtiene una respuesta definitiva en la misma interacción — "tu orden se creó" o "tu tarjeta fue rechazada" — sin ambigüedad sobre si la operación ocurrió o no.
#Orientado a eventos: indirecto, asíncrono, débilmente acoplado
En un diseño orientado a eventos, un servicio publica un evento — un hecho sobre algo que ya ocurrió, como OrderCreated — en un broker (Kafka, RabbitMQ, SNS/SQS, etc.) sin saber ni importarle quién, si es que alguien, va a reaccionar a él. Los servicios interesados se suscriben de forma independiente. El trabajo del productor termina en el momento en que el evento queda publicado de forma durable; no espera, ni siquiera conoce, el procesamiento posterior.
Esto es lo que desacopla a los servicios: el Servicio de Órdenes no tiene ninguna dependencia en tiempo de compilación ni de ejecución con Inventario, Pagos o Notificaciones — solo depende de la forma del evento que publica. Puedes añadir un quinto suscriptor mañana sin tocar el Servicio de Órdenes en absoluto. Esa es la ganancia estructural, y por eso las arquitecturas orientadas a eventos escalan tanto a nivel organizacional como técnico: un equipo puede ser dueño de un consumidor sin necesitar un cambio, ni coordinación, del equipo que produce el evento.
#Lo que sacrificas: consistencia y respuestas fáciles
El trade-off es consistencia e inmediatez. El cliente del diagrama anterior recibe un 202 Accepted, no una confirmación de que la orden se completó de punta a punta — puede resultar que el inventario sea insuficiente dos eventos después. El sistema se vuelve eventualmente consistente: correcto una vez que todos los eventos relevantes se propagaron y procesaron, pero no correcto en ningún instante puntual que puedas señalar. Eso obliga a decisiones de diseño reales que la versión request-response no tenía: ¿qué muestra la UI mientras la orden está "pendiente"? ¿Qué pasa si PaymentFailed llega después de InventoryReserved — necesitas una acción compensatoria (liberar el stock)? Esta es la semilla del patrón saga, donde una secuencia de transacciones locales coordinadas mediante eventos (o un orquestador explícito) reemplaza una gran transacción distribuida.
| Dimensión | Request-response | Orientado a eventos |
|---|---|---|
| Acoplamiento | Fuerte — quien llama conoce la dirección del destinatario y debe llamarlo directamente | Débil — el productor solo depende del esquema del evento, no de ningún consumidor |
| Disponibilidad | Producto de la disponibilidad de cada salto; un servicio caído rompe la cadena | Solo la disponibilidad del productor; los consumidores pueden atrasarse o reiniciar sin afectarla |
| Consistencia | Fuerte e inmediata — conoces el resultado antes de que retorne la llamada | Eventual — la corrección llega después de propagar y procesar |
| Aislamiento de fallos | Pobre — los fallos se propagan y se amplifican (los timeouts se acumulan) | Bueno — un consumidor lento o caído solo hace crecer un backlog, no una caída general |
| Facilidad de depuración | Mayor — un solo call stack, un solo trace | Menor — la causalidad se reparte entre productores, consumidores y el tiempo |
| Mejor encaje | Cualquier cosa que necesite una respuesta inmediata y autoritativa (autenticación, autorización de pago) | Fan-out, flujos que abarcan muchos servicios, cualquier cosa que tolere un retraso corto |
La mayoría de los sistemas reales no son puramente uno u otro. Un servicio típico expone una API síncrona para todo lo que un cliente necesita responder de inmediato (consultar el estado de una orden, autorizar un pago) y emite eventos para todo lo demás que puede reaccionar de forma independiente y asíncrona (enviar un correo de confirmación, actualizar un modelo de recomendaciones, sincronizar un data warehouse). Lo que esta pregunta realmente evalúa no es "cuál es mejor" — es si reconoces qué partes de un flujo determinado necesitan genuinamente una respuesta inmediata y consistente, y cuáles se sirven mejor con un hecho difundido a quien le interese.