El problema de la interoperabilidad
Imagine que es médico y atiende a un nuevo paciente que ha visitado varios hospitales, se ha sometido a distintas pruebas y actualmente toma varios medicamentos. Sin embargo, en este momento toda esa información crítica está dispersa entre diferentes sistemas que no se comunican entre sí de manera eficaz. Este es el problema de interoperabilidad de la sanidad.
Los sistemas de TI sanitarios están profundamente fragmentados. Cada hospital, clínica, laboratorio y compañía de seguros almacena los datos de los pacientes de forma diferente: con bases de datos propias, formatos propietarios y APIs incompatibles. Cuando los pacientes cambian de proveedor, su historial médico no les sigue de forma fluida. Sus resultados de laboratorio están en un sistema, las recetas en otro y las imágenes diagnósticas en un tercero. Los médicos pierden tiempo buscando información o, lo que es peor, tomando decisiones con datos incompletos.
Cada nueva conexión entre sistemas requiere desarrollo personalizado. El registro del paciente del Hospital «A» no se parece en nada al de la Clínica «B». Las APIs son inconsistentes. Los formatos de datos varían enormemente y la información crítica se pierde en la traducción. Alergias, medicamentos y procedimientos anteriores, todo disperso entre sistemas incompatibles que no pueden intercambiar mensajes coherentes.
Las organizaciones sanitarias quedan atrapadas por sistemas propietarios. Cambiar de proveedor implica reconstruir todas las integraciones desde cero: una tarea costosa y arriesgada que pocas pueden permitirse.
FHIR: El lenguaje universal de la sanidad
FHIR (Fast Healthcare Interoperability Resources) está revolucionando la comunicación entre los sistemas sanitarios. Piense en él como un vocabulario universal que cualquier sistema sanitario puede entender. En lugar de construir puentes a medida entre cada par de sistemas, cada organización se conecta a un servidor FHIR utilizando el mismo lenguaje estandarizado.
Patient, Observation, Medication, Condition: todos los datos sanitarios de todas las clínicas utilizan las mismas estructuras de recursos. Un registro Patient del Hospital «A» es idéntico al de la Clínica «B». No más analizadores sintácticos personalizados ni capas de transformación de datos.
Internamente, FHIR es una API RESTful, por lo que todos los servidores FHIR admiten las mismas operaciones:
-
GET /Patient/001– recuperar datos del paciente -
GET /Observation?patient=001&code=blood-pressure– buscar observaciones -
POST /Patient– crear un nuevo registro de paciente
Sin embargo, la flexibilidad de FHIR genera nuevos problemas. El recurso Patient base tiene más de 50 campos opcionales. ¿Cuáles debería exigir su clínica pediátrica? ¿Su centro de cardiología? ¿Su sistema de seguros?
Los distintos equipos interpretan la especificación FHIR a su manera: uno almacena el peso del paciente en kilogramos, otro en libras. Un laboratorio codifica las pruebas con LOINC, otro inventa códigos locales. Los parámetros de búsqueda varían entre implementaciones.
Es probable que su hospital necesite flujos de trabajo específicos que el núcleo de FHIR no contempla. ¿Cómo aplica sus reglas de calidad de datos? ¿Qué operaciones de búsqueda personalizadas necesitan su equipo clínico y sus sistemas de integración?
Los proveedores suelen seleccionar subconjuntos de FHIR: el Sistema «A» admite la búsqueda de Patient por nombre; el Sistema «B» no. Su integración se rompe cuando cambia de proveedor, aunque ambos afirmen ser «conformes con FHIR». Sin restricciones, los sistemas «conformes con FHIR» siguen siendo incapaces de compartir datos significativos. Se obtiene interoperabilidad estructural (mismo formato JSON), pero se pierde la interoperabilidad semántica (significado compartido).
Por eso el siguiente paso —una Guía de Implementación (IG) a medida— compromete a todos con el mismo manual y convierte la promesa de FHIR en una realidad cotidiana.
La Guía de Implementación: su manual de normas FHIR
Una Guía de Implementación FHIR convierte la especificación FHIR en un contrato inequívoco adaptado a su organización.
En lugar de más de 50 campos opcionales de Patient, su IG especifica exactamente cuáles son obligatorios. Las clínicas pediátricas exigen la fecha de nacimiento y el contacto del tutor, mientras que los centros de cardiología requieren el peso y el historial de presión arterial.
Su IG define que el peso debe registrarse en kilogramos, que las fechas siguen el formato ISO y que las observaciones de presión arterial utilizan códigos LOINC específicos. No hay margen para suposiciones ni interpretaciones inconsistentes.
Mediante ValueSets y CodeSystems, su IG restringe el grupo sanguíneo a valores válidos (A+, B-, O+), los códigos de laboratorio a términos LOINC aprobados y los códigos de diagnóstico al subconjunto ICD-10 de su organización.
Las extensiones le permiten capturar «ciudadanía», «raza» o «nivel de cobertura del seguro» sin romper la compatibilidad con FHIR. Los datos permanecen estructurados y con capacidad de búsqueda al tiempo que satisfacen necesidades empresariales únicas.
Su IG enumera los parámetros de búsqueda que todo servidor debe admitir. Dado que cada proveedor implementa el mismo conjunto de consultas, puede cambiar de sistema con confianza.
Los servidores FHIR pueden validar los datos entrantes con los perfiles de su Guía de Implementación (IG), rechazando los registros incompletos o malformados antes de que entren en su sistema.
El resultado: «conforme con FHIR según nuestra IG» significa que los sistemas realmente funcionan juntos, no que simplemente comparten la misma estructura JSON.
Aunque FHIR proporciona los cimientos, las Guías de Implementación le permiten definir exactamente cómo usa su organización FHIR. Piense en FHIR como el inglés y en su IG como el libro de estilo de su empresa: el mismo idioma, pero con reglas específicas para su contexto.
Con múltiples servicios, equipos y proveedores trabajando con un mismo servidor FHIR, es necesario que todos hablen un mismo dialecto: qué campos son obligatorios, qué valores están permitidos y qué APIs deben ser compatibles. Esto significa que tanto una aplicación hospitalaria como un sistema de seguros pueden trabajar con los mismos datos Patient sin coordinación previa. Búsquedas como GET /Observation?patient=123&code=loinc|1234-5 se comportan igual en todos los servidores conformes, haciendo que la integración sea predecible.
Terminology: hablar el mismo idioma
Un ValueSet y un CodeSystem son recursos FHIR que representan sus vocabularios controlados. Definen qué códigos están permitidos en los campos codificados y garantizan una terminología coherente en todo su sistema.
¿Por qué importa esto? Un campo de «grupo sanguíneo» necesita valores específicos como A+, B-, O+, no texto aleatorio como «sangre roja» o «tipo genial». Los distintos ámbitos sanitarios utilizan diferentes sistemas de codificación: LOINC para resultados de laboratorio, SNOMED CT para términos clínicos e ICD-10-CM para diagnósticos.
El recurso CodeSystem define los códigos reales y sus significados, como si creara un diccionario específico de su dominio. El valor de visualización puede traducirse a múltiples idiomas, preservando el significado previsto independientemente del idioma utilizado.
A su vez, el recurso ValueSet selecciona qué códigos de uno o más CodeSystems están permitidos en contextos específicos: imagine un ValueSet de «Grupo Sanguíneo» que extrae únicamente ocho códigos (A+, A-, B+, B-, AB+, AB-, O+, O-) del extenso catálogo SNOMED. Diferentes ValueSets que extraen sus códigos específicos relacionados con el contexto pueden basarse en el mismo CodeSystem, pero servir a flujos de trabajo distintos.
Entre los beneficios se incluyen: garantizar que solo se utilicen códigos válidos en los campos codificados, prevenir errores de introducción de datos mediante la validación y habilitar la interoperabilidad semántica, de modo que los sistemas entiendan el significado y no solo la estructura. En lugar de aceptar cualquier valor de cadena de texto en los campos codificados, su sistema valida contra vocabularios predefinidos, asegurando que los datos clínicos utilicen terminología estandarizada que otros sistemas puedan interpretar correctamente. Este enfoque controlado transforma el caos del texto libre en datos estructurados y significativos que apoyan la toma de decisiones clínicas, el cumplimiento normativo y el análisis de datos y el aprendizaje automático.
Exploremos un ejemplo práctico: la gestión de zonas horarias en aplicaciones de salud electrónica. Cuando su aplicación presta servicio a pacientes de diferentes regiones, la programación precisa de citas requiere conocimiento de las zonas horarias. El recurso CodeSystem de FHIR proporciona una forma estructurada de definir y gestionar estos valores de zona horaria.
{
"url": "http://my-organization.io/pacakage-1/CodeSystem/timezone-codes",
"status": "active",
"content": "complete",
"resourceType": "CodeSystem",
"concept": [
{ "code": "America/Los_Angeles", "display": "Pacific Time (US & Canada)" },
{ "code": "Europe/Andorra", "display": "Central European Time (Andorra)" },
{ "code": "Australia/Melbourne", "display": "Australian Eastern Time (Melbourne)" }
]
}
Para aplicar reglas de validación usando nuestro CodeSystem, creamos un ValueSet que lo referencia: los perfiles siempre se vinculan a ValueSets y no directamente a CodeSystems. La URL canónica actúa como identificador único que permite a nuestro perfil referenciar este ValueSet, mientras que el atributo compose actúa como un lenguaje específico de dominio que define las reglas para incluir códigos de CodeSystems. En nuestro caso sencillo, incluimos todos los códigos de nuestro CodeSystem de zonas horarias.
{
"url": "http://my-organization.io/pacakage-1/ValueSet/timezone-codes",
"status": "active",
"resourceType": "ValueSet",
"compose": {
"include": [{ "system": "http://my-organization.io/pacakage-1/CodeSystem/timezone-codes" }]
}
}
Resultado: el servidor ahora rechaza cualquier código de zona horaria que no esté en esta lista, manteniendo las agendas precisas en todo el mundo.
Extensiones: añadir sus campos personalizados
Extensiones = recursos FHIR + sus campos personalizados para los recursos existentes. Le permiten añadir datos que no existen en los recursos FHIR estándar sin bifurcar el estándar.
¿Por qué tomarse esta molestia? El recurso Patient básico carece de «ciudadanía», «raza» o «nivel de cobertura del seguro», pero nuestros requisitos empresariales y médicos dependen de esta información. Recuerde, FHIR es una columna vertebral: completo, pero no una ontología médica exhaustiva.
Beneficios clave
- Añada campos específicos del dominio y mantenga una conformidad con FHIR del 100 %.
- Mantenga la interoperabilidad al tiempo que captura sus requisitos únicos.
- Almacene datos personalizados en un formato estructurado y con capacidad de búsqueda, nunca enterrados en texto libre.
En lugar de modificar los recursos FHIR básicos o usar campos de texto no estructurado, su sistema captura datos adicionales precisos en un formato estandarizado y con capacidad de búsqueda. Este enfoque estructurado garantiza que los datos personalizados sigan siendo consultables e intercambiables, preservando al mismo tiempo la promesa de interoperabilidad de FHIR.
El ValueSet se vincula a la extensión
Con nuestro ValueSet definido, ahora podemos vincularlo a nuestra extensión de zona horaria. La referencia de vinculación apunta a la URL canónica de nuestro ValueSet, mientras que la fuerza de vinculación se establece como «required» para garantizar una validación estricta. Esto significa que el servidor FHIR rechazará cualquier recurso que use códigos de zona horaria que no estén en nuestro ValueSet.
{
"url": "http://my-organization.io/package-1/time-zone",
"baseDefinition": "http://hl7.org/fhir/StructureDefinition/Extension",
"abstract": false,
"name": "TimeZone",
"status": "active",
"kind": "complex-type",
"type": "Extension",
"derivation": "constraint",
"resourceType": "StructureDefinition",
"context": [{ "expression": "Patient", "type": "element" }],
"differential": {
"element": [
{
"path": "Extension.url",
"id": "Extension.url",
"fixedUri": "http://my-organization.io/package-1/time-zone"
},
{
"id": "Extension.value[x]",
"path": "Extension.value[x]",
"type": [{ "code": "code" }],
"min": 1,
"binding": {
"strength": "required",
"valueSet": "http://my-organization.io/pacakage-1/ValueSet/timezone-codes"
}
}
]
}
}
Perfiles: adaptando FHIR a sus necesidades
Perfiles = recursos FHIR + sus restricciones sobre ellos. Hacen que los recursos abstractos funcionen para sus necesidades específicas. FHIR proporciona un conjunto de recursos con un esquema específico, y la mayoría de los campos del recurso son opcionales por defecto.
¿Por qué crear un perfil? Una clínica de cardiología necesita datos del paciente diferentes a los de una clínica pediátrica. Cada especialidad médica tiene directrices clínicas y requisitos de notificación únicos que determinan qué datos deben recopilarse y cómo. Los requisitos legales también varían según el país y la especialidad.
En lugar de aceptar cualquier recurso Patient que cumpla la especificación FHIR base, un perfil dirige a su sistema a aceptar únicamente los registros que satisfagan sus requisitos clínicos o empresariales específicos y garantiza que su flujo de datos recopile información que mejore la calidad y la exhaustividad de los datos. Este enfoque orientado reduce los errores de integración y garantiza la coherencia de los datos en todo su ecosistema sanitario.
Examinemos un perfil Patient que aplica la calidad de datos y la conciencia de zona horaria en nuestra aplicación sanitaria. Este perfil muestra cómo combinar las capacidades básicas de FHIR con extensiones personalizadas para satisfacer necesidades empresariales específicas.
El perfil requiere tres elementos clave:
-
Nombre del paciente (obligatorio para una identificación correcta)
-
Género (obligatorio para un contexto clínico preciso)
-
Nuestra extensión Timezone (obligatoria para la programación de citas)
Al hacer obligatorios estos campos e incorporar nuestra extensión de zona horaria, garantizamos una recopilación de datos coherente en todo nuestro sistema.
{
"url": "http://my-organization.io/package-1/my-patient",
"baseDefinition": "http://hl7.org/fhir/StructureDefinition/Patient",
"name": "MyPatient",
"status": "active",
"kind": "resource",
"type": "Patient",
"abstract": false,
"derivation": "constraint",
"resourceType": "StructureDefinition",
"differential": {
"element": [
{
"id": "Patient.name",
"path": "Patient.name",
"min": 1
},
{
"id": "Patient.gender",
"path": "Patient.gender",
"min": 1
},
{
"id": "Patient.extension",
"path": "Patient.extension",
"min": 1,
"slicing": {
"rules": "open",
"discriminator": [{ "path": "url", "type": "value" }]
}
},
{
"min": 1,
"max": "1",
"sliceName": "TimeZone",
"path": "Patient.extension",
"id": "Patient.extension:TimeZone",
"type": [
{
"profile": [ "http://my-organization.io/package-1/time-zone" ],
"code": "Extension"
}
]
}
]
}
}
Nota: por muy especializados que sean sus perfiles —ya sea heredando de múltiples perfiles o añadiendo reglas de validación estrictas—, cualquier recurso que supere su validación de perfil sigue siendo un recurso FHIR válido en su núcleo. Otros sistemas FHIR pueden seguir trabajando con sus recursos, aunque no entiendan las reglas específicas de su perfil. Eso es lo que hace que FHIR sea verdaderamente potente: se obtienen tanto la estandarización como la flexibilidad.
Ejemplo de paciente mínimo válido según la versión final de nuestro perfil:
{
"meta": { "profile": ["http://my-organization.io/package-1/my-patient"] },
"extension": [
{
"url": "http://my-organization.io/package-1/time-zone",
"valueCode": "America/Los_Angeles"
}
],
"name": [{ "given": ["John"], "family": "Doe"}],
"gender": "male",
"resourceType": "Patient"
}
SearchParameter: encontrar lo que necesita
SearchParameter = recursos FHIR + sus capacidades de búsqueda personalizadas. Le permiten definir nuevas formas de buscar y filtrar recursos más allá de los parámetros de búsqueda estándar de FHIR.
¿Por qué ampliar la búsqueda? Los parámetros de búsqueda estándar de FHIR como «name» o «birthdate» son útiles, pero los flujos de trabajo del mundo real exigen consultas más enriquecidas: encontrar pacientes por campos personalizados (extensiones), localizar todos los resultados de laboratorio por encima de un umbral, o buscar en múltiples recursos en una sola consulta.
Los distintos equipos necesitan diferentes formas de encontrar datos: el clínico por síntomas y diagnósticos, el de facturación por seguro y códigos de procedimiento. En lugar de construir lógica de consulta compleja en el lado del cliente o mantener puntos de acceso de búsqueda personalizados, sus definiciones de SearchParameter ponen las consultas avanzadas a disposición a través de las APIs estándar de FHIR. Este enfoque estandarizado garantiza que todos los sistemas puedan realizar las mismas búsquedas de forma coherente.
Ejemplo: reutilicemos nuestra extensión de zona horaria para identificar pacientes dentro de zonas horarias específicas. Si un recurso Patient incluye una extensión que especifica su zona horaria, un SearchParameter puede usar FHIRPath para filtrar Patients en función del valor de esta extensión. Esto permite búsquedas como GET /Patient?timezone=America/Los_Angeles para recuperar pacientes en la zona horaria del Pacífico.
{
"url": "http://my-organization.io/package-1/SearchParameter/Patient-timeZone",
"id": "Patient-timeZone",
"base": ["Patient"],
"description": "Search patient by their time zone",
"expression": "Patient.extension.where(url='http://my-organization.io/package-1/time-zone').value",
"name": "timezone",
"status": "active",
"type": "token",
"code": "timezone",
"resourceType": "SearchParameter"
}
Cómo funciona FHIRPath (recorrido rápido)
- Navegación por puntos –
Patient.address.cityrecorre el árbol JSON como la notación de objetos. - Filtro
where()–extension.where(url='…')conserva solo los elementos coincidentes. - Conversión
ofType()–value.ofType(Quantity)delimita los campos polimórficos (que admiten más de un tipo de dato). - Encadenamiento – puede combinar estos elementos para alcanzar cualquier valor anidado.
Dado que todos los servidores entienden FHIRPath, la misma expresión produce resultados idénticos entre proveedores.
Su IG puede requerir compatibilidad con parámetros de búsqueda específicos. Esto garantiza que todas las implementaciones proporcionen las capacidades de búsqueda que su organización necesita.
Operaciones: lógica de negocio del dominio
Operaciones = API FHIR estandarizada + sus puntos de acceso personalizados específicos del dominio.
Le permiten definir métodos API complejos más allá de las simples operaciones CRUD sobre recursos.
¿Por qué definir operaciones? Los flujos de trabajo sanitarios a veces necesitan calcular interacciones farmacológicas, generar informes clínicos o procesar comprobaciones complejas de elegibilidad. Las operaciones REST estándar de FHIR (GET, POST, PUT, DELETE) funcionan bien para la gestión básica de recursos, pero no ejecutan lógica de negocio sofisticada.
OperationDefinition describe la interfaz de su operación personalizada: parámetros de entrada, formato de salida y documentación del comportamiento.
Ejemplo: Operación personalizada Patient/$schedule-teleconsultation-window
En entornos de atención distribuida, especialmente con la telemedicina, la programación debe tener en cuenta las zonas horarias tanto del paciente como del proveedor. Una operación FHIR personalizada puede automatizar la coordinación de ventanas de tiempo adecuadas para las consultas virtuales.
Esta operación admite parámetros de entrada opcionales para personalizar la lógica de programación:
- practitioner (Reference) Con quién desea programar la cita el paciente. Una referencia a un recurso Practitioner o PractitionerRole. Su disponibilidad se utiliza para calcular los intervalos posibles.
- daysAhead (integer, por defecto: 7) Con cuánta anticipación mirar. Limita la búsqueda a los próximos N días. Útil para evitar cálculos innecesarios.
- slotDuration (Duration, por defecto: 30 minutos) Duración mínima de la cita. Filtra los intervalos más cortos; por ejemplo, una consulta debe tener al menos 30 minutos de duración.
Estos parámetros ayudan al cliente (p. ej., una aplicación del paciente o una herramienta de coordinación de la atención) a adaptar el resultado a restricciones del mundo real como las agendas del proveedor, las necesidades del paciente o las políticas del sistema.
{
"resourceType": "OperationDefinition",
"id": "schedule-teleconsultation-window",
"url": "http://my-organization.io/package-1/OperationDefinition/schedule-teleconsultation-window",
"name": "ScheduleTeleconsultationWindow",
"status": "active",
"kind": "operation",
"code": "schedule-teleconsultation-window",
"resource": ["Patient"],
"system": false,
"type": true,
"instance": true,
"parameter": [
{
"name": "practitioner",
"use": "in",
"type": "Reference",
"min": 1,
"max": "1",
"documentation": "Practitioner to check availability for"
},
{
"name": "daysAhead",
"use": "in",
"min": 0,
"max": "0",
"type": "integer",
"documentation": "Number of days into the future to check"
},
{
"name": "slotDuration",
"use": "in",
"min": 0,
"max": "1",
"type": "Duration",
"documentation": "Minimum desired duration for appointment slot"
},
{
"name": "availableSlot",
"use": "out",
"min": 1,
"max": "100",
"type": "BackboneElement",
"part": [
{ "name": "start", "use": "out", "type": "dateTime", "min": 1, "max": "1" },
{ "name": "end", "use": "out", "type": "dateTime", "min": 1, "max": "1" }
]
}
]
}
Nota: definir una OperationDefinition en su IG documenta la interfaz y los requisitos de la operación, pero no implementa automáticamente la funcionalidad: su servidor FHIR debe proporcionar la implementación real.
Dar soporte a todas las operaciones de todas las guías de implementación existentes sería poco práctico y requeriría muchos recursos. En cambio, los servidores FHIR suelen implementar las operaciones de uso común de las IGs públicas más ampliamente adoptadas y ofrecen la posibilidad de ampliar la API FHIR con sus propias operaciones. Por ejemplo, Aidbox ofrece un patrón flexible de API Gateway a través de su funcionalidad «App», que le permite implementar operaciones personalizadas mediante funciones lambda o microservicios dedicados que se integran a la perfección con el servidor FHIR.
Distribución y empaquetado
Las Guías de Implementación FHIR pueden distribuirse como paquetes NPM, lo que facilita su versionado, uso compartido e integración en diferentes sistemas. Este enfoque aprovecha el conocido ecosistema NPM que los desarrolladores ya utilizan para las dependencias de JavaScript/TypeScript.
Nuestro package.json mínimo para una IG FHIR podría tener este aspecto:
{
"name": "my.organization.fhir",
"version": "0.0.1",
"description": "My Organization IG FHIR Package",
"author": "My Organization",
"dependencies": {
"hl7.fhir.r4.core": "4.0.1"
}
}
Esta estructura de paquete permite el versionado semántico de su IG, la gestión de dependencias de las especificaciones FHIR base y otras IGs, una distribución sencilla a través de registros NPM, la identificación clara de la compatibilidad con la versión de FHIR y la integración automatizada de herramientas.
Para empaquetar la Guía de Implementación, navegue hasta el directorio de su IG y ejecute: npm pack
Esto creará un archivo .tgz como: my-organization-fhir-ig-package-1.0.0.tgz. Alternativamente, puede crear un archivo tarball manualmente.
El ejemplo de Guía de Implementación del artículo está disponible en: https://storage.googleapis.com/my-implementation-guide/my.organization.fhir-0.0.1.tgz
Cree su instancia de Aidbox y pruebe la guía de implementación en http://aidbox.app.
Para cargar la IG, siga la documentación.
Ejemplos reales de IGs
Las IGs de FHIR no son meramente teóricas: son fundamentales para los esfuerzos de interoperabilidad del mundo real. A continuación se presentan algunas guías ampliamente adoptadas:
- US Core: define el conjunto mínimo de datos y las restricciones para el intercambio de datos clínicos en los Estados Unidos. Muchas APIs nacionales y sistemas de historia clínica electrónica se construyen sobre ella.
- International Patient Summary (IPS): permite el intercambio transfronterizo de resúmenes de pacientes. Se utiliza en la UE e internacionalmente.
- mCODE (Minimal Common Oncology Data Elements): adapta FHIR a la oncología, permitiendo datos de cáncer estructurados y analizables para ensayos clínicos, atención e investigación.
Estos ejemplos muestran cómo las IGs abordan dominios y casos de uso específicos, estableciendo un estándar para la calidad y la interoperabilidad de los datos. Al examinarlos, puede alinear sus propias IGs con las mejores prácticas de la comunidad.
Véase también: Desarrollo ágil de FHIR IG.






