Si alguna vez guardaste una URL en una base de datos y después te arrepentiste, esto es para vos.
Es un escenario conocido: un servicio necesita mantener una referencia a un recurso que vive en otro servicio. La solución más obvia es guardar la URL. Funciona, hasta que el host cambia, la API sube de versión, o el equipo decide reestructurar los paths. De repente todas las referencias guardadas están rotas, y rastrear el impacto se convierte en un problema mayor de lo que debería ser.
El problema de fondo es que una URL mezcla dos cosas distintas: qué es el recurso y dónde está. Cuando guardás una URL estás apostando a que esa ubicación no va a cambiar. En sistemas que evolucionan, esa apuesta suele perderse.
La idea
¿Qué pasaría si en lugar de guardar dónde está el recurso, guardás un identificador propio que un gateway sabe cómo resolver?
comercio:pedidos/orden:id=ARG-2024-00091872
finanzas:cuentas/cliente:estado:id=109234
salud:cobertura/credencial:patient-id=12345678
Quien guarda la referencia no necesita saber dónde vive el recurso ni cómo se accede. Esa responsabilidad la tiene el gateway. Si la API cambia, si el servicio migra, si aparece un sistema nuevo: solo cambia el resolver. Las referencias guardadas siguen siendo válidas.
A este esquema lo llamé Delegated Resource Identifier (DRI).
Lo que este patrón no es
- No es un estándar
- Requiere un gateway como intermediario: no aplica cuando el cliente necesita acceder directamente al recurso sin pasar por ningún intermediario
- No impone una taxonomía de contextos: cada equipo define la suya
Es una convención útil cuando necesitás referencias persistentes a recursos en un ecosistema controlado, y querés centralizar la lógica de resolución.
Cómo se construye
El identificador tiene dos partes separadas por /:
<contexto>/<recurso>
- Contexto (lado izquierdo): identifica el dominio que sabe resolver este tipo de recurso. El gateway lo usa para rutear.
- Recurso (lado derecho): identifica el recurso concreto. Su estructura la define quien implementa el resolver.
comercio:pedidos/orden:id=ARG-2024-00091872
└─── ruteo ──────┘└─── recurso concreto ──┘
Los : separan niveles jerárquicos. El = asigna valores. Cada lado define su propia convención interna.
El identificador lo construye quien guarda la referencia, a partir del dato que ya tiene y el contexto que conoce. No requiere ninguna llamada externa. Un servicio de facturación que recibe el ID de una orden sabe que pertenece a comercio:pedidos y construye el DRI al momento de persistir la referencia.
El contexto puede omitirse si el gateway tiene un resolver por defecto:
/orden:id=ARG-2024-00091872
Algunos casos de uso
E-commerce: recuperar una orden
Un servicio de atención al cliente guarda referencias a órdenes que pueden venir de distintos canales: tienda propia, marketplace, app móvil. Cada canal tiene su propia API.
comercio:pedidos/orden:id=ARG-2024-00091872
comercio:pedidos/orden:id=MKT-2024-00034521
El resolver de comercio:pedidos determina a qué canal pertenece cada orden a partir del prefijo del ID y rutea hacia la API correspondiente. El identificador es estable aunque la API del canal cambie.
Fintech: estado de cuenta de un cliente
Un banco con sistemas legacy y modernos conviviendo. El resolver determina en qué sistema vive el cliente según el valor del ID: clientes con id < 50000 en el sistema legacy, el resto en el moderno.
finanzas:cuentas/cliente:estado:id=109234
finanzas:cuentas/cliente:estado:id=002871
El resolver encapsula también la decisión de qué versión de la API usar. Y acá aparece algo interesante: el DRI tiene dos momentos de vida. Cuando se persiste es solo el identificador. Cuando se usa para consultar, puede enriquecerse con contexto adicional usando la misma sintaxis:
finanzas:cuentas/cliente:estado:id=109234:fecha=20260101
El resolver puede usar esa fecha para determinar qué versión de la API corresponde. El DRI persistido no cambia; el contexto adicional se agrega en el momento de la consulta.
Salud: credencial de cobertura de un afiliado
La cobertura de un afiliado puede cambiar en el tiempo: migración de proveedor, períodos sin cobertura, cobertura en más de uno. Guardar el proveedor como dato fijo generaría referencias desactualizadas.
salud:cobertura/credencial:patient-id=12345678
El resolver aplica una estrategia de fallback: consulta al primer proveedor disponible y si no encuentra la credencial prueba con el siguiente. El DRI resuelve en el momento de la consulta, reflejando siempre el estado actual.
Multinacional con tenant: proveedor por entidad legal
Una plataforma SaaS con operaciones en múltiples países. Cada país tiene su propio sistema, su propia API y su propio formato de identificador fiscal.
tenant:acme:ar/proveedor:cuit=20123456789
tenant:acme:cl/proveedor:rut=76354921-5
tenant:acme:mx/proveedor:rfc=XYZ123456789
El lado izquierdo combina tenant y entidad legal por país. El lado derecho respeta la convención local. Agregar una nueva filial o un nuevo tenant es registrar un resolver adicional, sin tocar las referencias existentes. La jerarquía del contexto crece naturalmente con el sistema.
Cómo funciona el gateway
El flujo de resolución es simple: el gateway recibe el identificador, extrae el contexto y delega al resolver correspondiente.
cliente → gateway → resolver(comercio:pedidos) → servicio real
- Recibe el identificador
- Extrae el contexto (lado izquierdo)
- Delega al resolver registrado para ese contexto
- El resolver obtiene el recurso y devuelve la respuesta
El gateway no conoce recursos concretos. A modo de referencia orientativa, una posible implementación en Java:
gateway.register("comercio:pedidos", new OrderResolver());
gateway.register("finanzas:cuentas", new AccountResolver());
gateway.register("salud:cobertura", new CoverageResolver());
public interface ResourceResolver {
Response resolve(ResourceIdentifier identifier);
}
Preferencias opcionales
El identificador admite expresar preferencias sobre cómo debe resolverse el recurso, con una sintaxis inspirada en el header Accept de HTTP. Por ejemplo, al consultar medios de pago se puede indicar preferencia por débito sobre crédito:
pagos:medios/disponibles:cliente:id=109234;debito,q=0.9;credito,q=0.7
El significado de q lo define el contrato entre quien construye la referencia y quien la resuelve. El gateway no necesita interpretarlo. Esta capacidad es completamente opcional.
Lo implementé en Java y me resultó útil en la práctica. Si lo probás en tu contexto o tenés ideas para mejorarlo, me interesa leerlo en los comentarios.
Top comments (0)