{"id":128,"date":"2026-03-09T02:42:15","date_gmt":"2026-03-09T02:42:15","guid":{"rendered":"https:\/\/blog.rebalai.com\/es\/2026\/03\/09\/arquitectura-impulsada-por-eventos-2026-por-qu\/"},"modified":"2026-03-18T22:00:21","modified_gmt":"2026-03-18T22:00:21","slug":"arquitectura-impulsada-por-eventos-2026-por-qu","status":"publish","type":"post","link":"https:\/\/blog.rebalai.com\/es\/2026\/03\/09\/arquitectura-impulsada-por-eventos-2026-por-qu\/","title":{"rendered":"Arquitectura Impulsada por Eventos 2026: Por Qu\u00e9 los Microservicios se Est\u00e1n Pasando al Event Streaming"},"content":{"rendered":"<p>Hace unos meses estaba depurando un problema en <a href=\"https:\/\/m.do.co\/c\/06956e5e2802\" title=\"DigitalOcean para Producci\u00f3n\" rel=\"nofollow sponsored\" target=\"_blank\">producci\u00f3n<\/a> que me ten\u00eda completamente perdido. Ten\u00edamos un servicio de \u00f3rdenes que llamaba s\u00edncronamente a un servicio de inventario, que a su vez llamaba a un servicio de pagos, que llamaba a un servicio de notificaciones. Una cadena cl\u00e1sica de REST sobre REST. El problema: cuando el servicio de notificaciones se pon\u00eda lento (y se pon\u00eda lento bastante seguido), la latencia se propagaba hacia atr\u00e1s como un domin\u00f3. Las \u00f3rdenes empezaban a fallar. Los usuarios ve\u00edan errores 500. Mi tel\u00e9fono no paraba.<\/p>\n<p>Ese d\u00eda empec\u00e9 a tomar en serio <a href=\"https:\/\/blog.rebalai.com\/es\/2026\/03\/09\/configuracin-de-github-actions-para-aplicaciones-p\/\" title=\"lo que\">lo que<\/a> varios colegas llevaban dici\u00e9ndome desde 2024: la arquitectura de microservicios que todos construimos durante la d\u00e9cada pasada tiene un problema estructural que los patrones de resiliencia tradicionales no resuelven del todo.<\/p>\n<h2>El Problema Real con los Microservicios S\u00edncronos<\/h2>\n<p>Cuando digo &#8220;microservicios s\u00edncronos&#8221; me refiero a ese patr\u00f3n donde cada servicio habla directamente con otros a trav\u00e9s de HTTP o gRPC, esperando una respuesta antes de continuar. Es intuitivo. Es f\u00e1cil de debuggear localmente. Y durante a\u00f1os funcion\u00f3 razonablemente bien.<\/p>\n<p>El problema es el acoplamiento temporal. Dos servicios que se comunican s\u00edncronamente est\u00e1n acoplados <a href=\"https:\/\/blog.rebalai.com\/es\/2026\/03\/05\/claude-vs-gpt-4o-vs-gemini-20-qu-modelo-de-ia-usar\/\" title=\"en el\">en el<\/a> tiempo \u2014 los dos tienen que estar disponibles al mismo tiempo para que la operaci\u00f3n funcione. Suena obvio cuando lo dices as\u00ed, pero las consecuencias son m\u00e1s profundas de <a href=\"https:\/\/blog.rebalai.com\/es\/2026\/03\/09\/configuracin-de-github-actions-para-aplicaciones-p\/\" title=\"lo que\">lo que<\/a> parece.<\/p>\n<p>En un sistema con 15 servicios donde cada llamada tiene 99.9% de disponibilidad, la disponibilidad compuesta de una cadena de 10 llamadas es aproximadamente 99%. Eso son unas 7 horas de downtime al mes. Empiezas a a\u00f1adir circuit breakers, retries con backoff exponencial, timeouts en cascada&#8230; y de repente tienes un sistema complicado que sigue fallando, solo que de maneras m\u00e1s interesantes.<\/p>\n<p>No estoy diciendo que los microservicios s\u00edncronos sean malos per se. Para ciertas operaciones \u2014 consultas de lectura, validaciones en tiempo real, operaciones que genuinamente necesitan una respuesta inmediata \u2014 siguen siendo la herramienta correcta. <a href=\"https:\/\/blog.rebalai.com\/es\/2026\/03\/09\/configuracin-de-github-actions-para-aplicaciones-p\/\" title=\"lo que\">Lo que<\/a> cambi\u00f3 en los \u00faltimos dos a\u00f1os es la forma en que los equipos piensan sobre qu\u00e9 operaciones realmente necesitan ser s\u00edncronas.<\/p>\n<p>La respuesta, sorprendentemente, es que son muchas menos de las que cre\u00edamos.<\/p>\n<h2>Qu\u00e9 Cambi\u00f3 en 2025-2026<\/h2>\n<p>El <a href=\"https:\/\/blog.rebalai.com\/es\/2026\/03\/09\/event-driven-architecture-in-2026-why-microservice\/\" title=\"event streaming\">event streaming<\/a> no es nuevo. Kafka existe desde 2011. <a href=\"https:\/\/blog.rebalai.com\/es\/2026\/03\/09\/configuracin-de-github-actions-para-aplicaciones-p\/\" title=\"lo que\">Lo que<\/a> s\u00ed cambi\u00f3 es la madurez del ecosistema alrededor de \u00e9l y, honestamente, el costo de operarlo.<\/p>\n<p><strong>Redpanda<\/strong> \u2014 que nunca dependi\u00f3 de ZooKeeper y usa Raft desde su origen, con compatibilidad casi perfecta con la API de Kafka \u2014 baj\u00f3 significativamente la barrera de entrada. En mi equipo pasamos de gestionar un cl\u00faster de Kafka con 5 brokers m\u00e1s ZooKeeper a un cl\u00faster de Redpanda con 3 nodos. El consumo de memoria cay\u00f3 a la mitad. No tengo que mentir: fue un alivio operacional real.<\/p>\n<p>Tambi\u00e9n madur\u00f3 mucho el patr\u00f3n <strong>Transactional Outbox<\/strong>. Antes, la pregunta &#8220;\u00bfc\u00f3mo garantizo que el evento se publique si la base <a href=\"https:\/\/blog.rebalai.com\/es\/2026\/03\/08\/rag-profundo-estrategias-de-chunking-bases-de-dato\/\" title=\"de Datos\">de datos<\/a> falla a mitad de la transacci\u00f3n?&#8221; no ten\u00eda una respuesta limpia. Ahora hay librer\u00edas s\u00f3lidas \u2014 Debezium para CDC, Transactional Outbox con soporte nativo en varios ORMs \u2014 que hacen esto manejable.<\/p>\n<p>Y por supuesto, <strong>Apache Kafka 4.0<\/strong> sali\u00f3 en 2025 con el modo KRaft estable para <a href=\"https:\/\/m.do.co\/c\/06956e5e2802\" title=\"DigitalOcean para Producci\u00f3n\" rel=\"nofollow sponsored\" target=\"_blank\">producci\u00f3n<\/a>, <a href=\"https:\/\/blog.rebalai.com\/es\/2026\/03\/09\/configuracin-de-github-actions-para-aplicaciones-p\/\" title=\"lo que\">lo que<\/a> simplific\u00f3 bastante el modelo operacional para quienes no quer\u00edan cambiar de Kafka.<\/p>\n<h2>C\u00f3mo Se Ve Esto en C\u00f3digo Real<\/h2>\n<p>Dejame mostrarte el patr\u00f3n que adoptamos. Tenemos un servicio de \u00f3rdenes que antes hac\u00eda esto:<\/p>\n<pre><code class=\"language-python\"># Antes: el servicio llama s\u00edncronamente a inventario, pagos, y notificaciones\nasync def create_order(order_data: OrderCreate) -&gt; Order:\n    # Si cualquiera de estos falla, la orden falla\n    inventory_ok = await inventory_client.reserve(order_data.items)\n    if not inventory_ok:\n        raise HTTPException(status_code=409, detail=&quot;Stock insuficiente&quot;)\n\n    payment_result = await payment_client.charge(\n        user_id=order_data.user_id,\n        amount=order_data.total\n    )\n    if not payment_result.success:\n        # Ojo: aqu\u00ed ya reservamos inventario y tenemos que revertir\n        await inventory_client.release(order_data.items)\n        raise HTTPException(status_code=402, detail=&quot;Pago rechazado&quot;)\n\n    await notification_client.send_confirmation(order_data.user_id)\n\n    order = await db.save(order_data)\n    return order\n<\/code><\/pre>\n<p>El problema de esta versi\u00f3n, adem\u00e1s del acoplamiento temporal, es la l\u00f3gica de compensaci\u00f3n manual. Si el pago falla tengo que revertir el inventario. Si la notificaci\u00f3n falla&#8230; \u00bfqu\u00e9 hago? \u00bfRevierto todo? \u00bfDejo la orden sin confirmaci\u00f3n?<\/p>\n<p>Ahora el mismo flujo con <a href=\"https:\/\/blog.rebalai.com\/es\/2026\/03\/09\/event-driven-architecture-in-2026-why-microservice\/\" title=\"event streaming\">event streaming<\/a>:<\/p>\n<pre><code class=\"language-python\"># Despu\u00e9s: el servicio publica un evento y se desentiende del resto\nasync def create_order(order_data: OrderCreate) -&gt; Order:\n    async with db.transaction():\n        # Guardamos la orden en estado PENDING\n        order = await db.save(Order(\n            **order_data.dict(),\n            status=OrderStatus.PENDING\n        ))\n\n        # Usando el patr\u00f3n Outbox: el evento se guarda en la misma transacci\u00f3n\n        # Debezium o un worker lo publica a Kafka despu\u00e9s\n        await db.save(OutboxEvent(\n            aggregate_id=order.id,\n            event_type=&quot;OrderCreated&quot;,\n            payload=order.to_event_dict(),\n            created_at=datetime.utcnow()\n        ))\n\n    # Respuesta inmediata al cliente con el estado PENDING\n    # Los servicios downstream reaccionan al evento de forma as\u00edncrona\n    return order\n\n# <a href=\"https:\/\/blog.rebalai.com\/es\/2026\/03\/05\/claude-vs-gpt-4o-vs-gemini-20-qu-modelo-de-ia-usar\/\" title=\"en el\">En el<\/a> servicio de inventario (consumidor independiente):\n@kafka_consumer(topic=&quot;orders&quot;, event_type=&quot;OrderCreated&quot;)\nasync def handle_order_created(event: OrderCreatedEvent):\n    result = await inventory.try_reserve(event.items)\n\n    # Publica su propio evento seg\u00fan el resultado\n    event_type = &quot;InventoryReserved&quot; if result.success else &quot;InventoryFailed&quot;\n    await kafka.publish(&quot;inventory-events&quot;, {\n        &quot;order_id&quot;: event.order_id,\n        &quot;type&quot;: event_type,\n        &quot;reason&quot;: result.reason if not result.success else None\n    })\n<\/code><\/pre>\n<p>La diferencia fundamental: el servicio de \u00f3rdenes ya no sabe (ni le importa) si el inventario est\u00e1 disponible en ese momento. Publica un evento y termina. El servicio de inventario procesar\u00e1 el evento cuando pueda. Si est\u00e1 ca\u00eddo, lo procesar\u00e1 cuando se recupere \u2014 Kafka retiene los mensajes. La saga se ejecuta de forma as\u00edncrona, cada servicio publicando eventos que otros consumen.<\/p>\n<p>Esto no elimina la complejidad, ojo. La mueve. Ahora tienes que manejar la compensaci\u00f3n distribuida (el patr\u00f3n Saga), la eventual consistency, y los estados intermedios que el cliente puede ver. Pero es una complejidad m\u00e1s expl\u00edcita y, en mi experiencia, m\u00e1s manejable a largo plazo.<\/p>\n<h2>El Gotcha que Me Cost\u00f3 Dos D\u00edas<\/h2>\n<p>Aqu\u00ed va la parte que m\u00e1s me duele recordar: el <strong>event ordering<\/strong>.<\/p>\n<p>Kafka garantiza el orden de los mensajes dentro de una partici\u00f3n. <a href=\"https:\/\/blog.rebalai.com\/es\/2026\/03\/09\/configuracin-de-github-actions-para-aplicaciones-p\/\" title=\"lo que\">Lo que<\/a> yo no consider\u00e9 bien es que si particionas por <code>order_id<\/code> (que <a href=\"https:\/\/blog.rebalai.com\/es\/2026\/03\/08\/benchmarks-de-asistentes-de-cdigo-ia-pruebas-de-re\/\" title=\"es lo\">es lo<\/a> natural), todos los eventos de la misma orden van a la misma partici\u00f3n. Perfecto. El problema vino cuando empezamos a particionar un topic por <code>user_id<\/code> para paralelizar el procesamiento.<\/p>\n<p>Un usuario pod\u00eda tener dos \u00f3rdenes activas simult\u00e1neamente. Orden A se cre\u00f3 antes que Orden B, pero por un race condition en c\u00f3mo el producer asignaba particiones, el evento <code>OrderCreated<\/code> de Orden B lleg\u00f3 antes al consumidor que el de Orden A. El servicio de inventario proces\u00f3 Orden B primero, reserv\u00f3 los \u00faltimos 2 items del stock, y cuando lleg\u00f3 Orden A ya no hab\u00eda stock \u2014 aunque Orden A se hab\u00eda creado antes.<\/p>\n<p>\u00bfLa soluci\u00f3n? Para este caso espec\u00edfico necesit\u00e1bamos que el orden relativo entre \u00f3rdenes del mismo usuario se preservara. Pasamos a particionar el topic de \u00f3rdenes tambi\u00e9n por <code>user_id<\/code>. Suena simple en retrospectiva, pero encontrar el bug me tom\u00f3 dos d\u00edas de logs y mucho caf\u00e9.<\/p>\n<p>La lecci\u00f3n general: no asumas que el orden de procesamiento refleja el orden de creaci\u00f3n a menos que hayas dise\u00f1ado expl\u00edcitamente para eso. En sistemas event-driven el orden es algo que tienes que ganarte, no algo que viene gratis.<\/p>\n<h2>\u00bfCu\u00e1ndo <a href=\"https:\/\/blog.rebalai.com\/es\/2026\/03\/09\/webassembly-in-2026-where-it-actually-makes-sense\/\" title=\"Tiene Sentido\">Tiene Sentido<\/a> y Cu\u00e1ndo No?<\/h2>\n<p>No voy a venderte que migres todo a eventos. Ser\u00eda la respuesta f\u00e1cil \u2014 y equivocada.<\/p>\n<p>Los casos donde el <a href=\"https:\/\/blog.rebalai.com\/es\/2026\/03\/09\/event-driven-architecture-in-2026-why-microservice\/\" title=\"event streaming\">event streaming<\/a> realmente paga son:<\/p>\n<ul>\n<li><strong>Flujos de negocio largos y multi-paso<\/strong> donde la eventual consistency es aceptable (crear una orden, procesar pago, preparar env\u00edo \u2014 el usuario tolera esperar unos segundos para la confirmaci\u00f3n)<\/li>\n<li><strong>Integraci\u00f3n entre dominios<\/strong> donde los equipos son diferentes y no quieres que un dominio dependa del uptime de otro<\/li>\n<li><strong>Audit logs y event sourcing<\/strong> \u2014 tener el historial completo de eventos es valios\u00edsimo para debugging y compliance<\/li>\n<li><strong>Fanout<\/strong> \u2014 un evento que m\u00faltiples servicios necesitan procesar (un <code>UserRegistered<\/code> que dispara onboarding, analytics, email de bienvenida, etc.)<\/li>\n<\/ul>\n<p>Donde yo no lo usar\u00eda:<\/p>\n<ul>\n<li>Operaciones que genuinamente necesitan respuesta s\u00edncrona (\u00bfest\u00e1 este producto disponible en stock? \u2014 el usuario est\u00e1 esperando en la pantalla)<\/li>\n<li>Sistemas peque\u00f1os con 2-3 servicios donde la complejidad operacional de Kafka no se justifica<\/li>\n<li>Equipos sin experiencia en sistemas distribuidos que tienen deadline ma\u00f1ana \u2014 la curva de aprendizaje es real<\/li>\n<\/ul>\n<p>Y honestamente, no estoy 100% seguro de que este patr\u00f3n escale bien para todos los tama\u00f1os de equipo. <a href=\"https:\/\/blog.rebalai.com\/es\/2026\/03\/09\/configuracin-de-github-actions-para-aplicaciones-p\/\" title=\"lo que\">Lo que<\/a> funciona para un equipo de 8 personas con ownership claro de los topics puede volverse un caos de contratos de eventos sin versionar <a href=\"https:\/\/blog.rebalai.com\/es\/2026\/03\/09\/postgresql-performance-tuning-what-i-learned-optim\/\" title=\"en una\">en una<\/a> organizaci\u00f3n grande sin buena gobernanza.<\/p>\n<h2>Lo que Recomendar\u00eda Hoy<\/h2>\n<p>Si est\u00e1s empezando un proyecto nuevo con m\u00e1s de 3-4 servicios, dedicar\u00eda tiempo desde el inicio a identificar qu\u00e9 flujos son candidatos para eventos. No migres s\u00edncronamente todo \u2014 empieza con los flujos donde la latencia as\u00edncrona es aceptable y donde el acoplamiento entre servicios te est\u00e1 causando problemas reales.<\/p>\n<p>Para la <a href=\"https:\/\/m.do.co\/c\/06956e5e2802\" title=\"Infraestructura Cloud con DigitalOcean\" rel=\"nofollow sponsored\" target=\"_blank\">infraestructura<\/a>: si puedes evitar operar Kafka t\u00fa mismo, hazlo. Confluent Cloud y Redpanda Cloud han madurado bastante. Si tienes que operarlo on-prem, Redpanda es mi recomendaci\u00f3n actual sobre Kafka vanilla <a href=\"https:\/\/blog.rebalai.com\/es\/2026\/03\/09\/serverless-vs-containers-in-2026-a-practical-decis\/\" title=\"para Equipos\">para equipos<\/a> peque\u00f1os \u2014 menos overhead operacional es un factor real, y lo agradeces el domingo <a href=\"https:\/\/blog.rebalai.com\/es\/2026\/03\/09\/setting-up-github-actions-for-python-applications\/\" title=\"a las\">a las<\/a> 2am cuando no hay una alerta de ZooKeeper.<\/p>\n<p>Invierte <a href=\"https:\/\/blog.rebalai.com\/es\/2026\/03\/05\/claude-vs-gpt-4o-vs-gemini-20-qu-modelo-de-ia-usar\/\" title=\"en el\">en el<\/a> Transactional Outbox desde el principio. No publiques eventos directamente desde la l\u00f3gica de negocio sin garant\u00edas transaccionales \u2014 ese camino lleva a datos inconsistentes que son muy dif\u00edciles de debuggear.<\/p>\n<p>Y aprende los patrones Saga (coreograf\u00eda vs orquestaci\u00f3n) antes de empezar. La coreograf\u00eda \u2014 donde cada servicio reacciona a eventos y publica los suyos \u2014 es m\u00e1s desacoplada pero m\u00e1s dif\u00edcil de razonar sobre el flujo completo. La orquestaci\u00f3n \u2014 un servicio central que coordina la saga \u2014 es m\u00e1s visible pero introduce acoplamiento. Cu\u00e1l usar depende de tu caso.<\/p>\n<p>El problema del servicio de notificaciones lento que mencion\u00e9 al inicio lo resolv\u00ed, por cierto. Ahora el servicio de \u00f3rdenes publica un evento <code>OrderConfirmed<\/code> y el servicio de notificaciones lo consume de forma independiente. Si se pone lento, los eventos se acumulan <a href=\"https:\/\/blog.rebalai.com\/es\/2026\/03\/05\/claude-vs-gpt-4o-vs-gemini-20-qu-modelo-de-ia-usar\/\" title=\"en el\">en el<\/a> topic y los procesa cuando puede. Las \u00f3rdenes no fallan. Mi tel\u00e9fono descansa. Y yo, la verdad, tambi\u00e9n.<\/p>\n<p><!-- Reviewed: 2026-03-09 | Status: ready_to_publish | Changes: fixed downtime math (87min\u2192~7h for 99% uptime), corrected Redpanda\/ZooKeeper history (never used ZK), trimmed meta_description to ~155 chars, punched up section opener for cu\u00e1ndo-tiene-sentido, added personality to Redpanda recommendation, minor rhythm\/flow edits throughout --><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Hace unos meses estaba depurando un problema en producci\u00f3n que me ten\u00eda completamente perdido.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"site-sidebar-layout":"default","site-content-layout":"","ast-site-content-layout":"default","site-content-style":"default","site-sidebar-style":"default","ast-global-header-display":"","ast-banner-title-visibility":"","ast-main-header-display":"","ast-hfb-above-header-display":"","ast-hfb-below-header-display":"","ast-hfb-mobile-header-display":"","site-post-title":"","ast-breadcrumbs-content":"","ast-featured-img":"","footer-sml-layout":"","ast-disable-related-posts":"","theme-transparent-header-meta":"","adv-header-id-meta":"","stick-header-meta":"","header-above-stick-meta":"","header-main-stick-meta":"","header-below-stick-meta":"","astra-migrate-meta-layouts":"default","ast-page-background-enabled":"default","ast-page-background-meta":{"desktop":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"ast-content-background-meta":{"desktop":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"footnotes":""},"categories":[1],"tags":[],"class_list":["post-128","post","type-post","status-publish","format-standard","hentry","category-general"],"_links":{"self":[{"href":"https:\/\/blog.rebalai.com\/es\/wp-json\/wp\/v2\/posts\/128","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.rebalai.com\/es\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.rebalai.com\/es\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.rebalai.com\/es\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.rebalai.com\/es\/wp-json\/wp\/v2\/comments?post=128"}],"version-history":[{"count":14,"href":"https:\/\/blog.rebalai.com\/es\/wp-json\/wp\/v2\/posts\/128\/revisions"}],"predecessor-version":[{"id":624,"href":"https:\/\/blog.rebalai.com\/es\/wp-json\/wp\/v2\/posts\/128\/revisions\/624"}],"wp:attachment":[{"href":"https:\/\/blog.rebalai.com\/es\/wp-json\/wp\/v2\/media?parent=128"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.rebalai.com\/es\/wp-json\/wp\/v2\/categories?post=128"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.rebalai.com\/es\/wp-json\/wp\/v2\/tags?post=128"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}