Un élément, une liaison — et ses limites
Depuis FHIR DSTU2, chaque élément codé possède exactement une liaison — une règle qui associe l'élément à un ensemble de codes autorisés (un ValueSet) avec une force particulière. La force indique à quel point les codes doivent être respectés : required signifie que vous DEVEZ utiliser un code de cet ensemble ; extensible signifie d'en utiliser un s'il s'applique à votre concept, sinon vous pouvez utiliser d'autres codes ; preferred et example sont des suggestions progressivement plus souples. Pour des éléments simples comme Patient.gender (lié à AdministrativeGender avec la force required), ce modèle fonctionne parfaitement.
Mais à mesure que l'adoption de FHIR s'est élargie — à travers les juridictions, les domaines cliniques et les régimes réglementaires — le modèle à une seule liaison a atteint ses limites. Les auteurs de profils (les personnes qui rédigent des StructureDefinitions — des ensembles de contraintes superposées aux ressources FHIR de base) se heurtaient continuellement à des problèmes qu'un seul ValueSet ne pouvait pas exprimer.
La saga Extensible+Max
Le premier contournement fut le patron Extensible+Max. US Core avait besoin d'un moyen de dire : « utilisez les codes de ce petit ValueSet, mais si vous devez étendre, restez dans les limites de ce ValueSet plus large. » La solution fut l'extension maxValueSet, introduite dans STU3 et affinée dans R4.
Elle a immédiatement causé de la confusion. La spécification la décrivait comme « une liaison 'required' par-dessus la liaison extensible » — mais personne ne s'entendait sur ce que cela signifiait concrètement. La tension fondamentale, mise à nu dans un fil de 182 messages sur chat.fhir.org : Argonaut avait besoin de « utiliser ce code ou du texte libre » pour la conformité ONC — les hôpitaux avaient des problèmes de texte libre qui étaient « littéralement une chaîne de caractères dans le système local » (Jenni Syed). Mais aucune combinaison de forces de liaison ne pouvait exprimer cela. Josh Mandel a souligné que US Core Immunization liait vaccineCode à CVX avec à la fois extensible et max — vers le même ValueSet : « Du point de vue de l'interopérabilité, je ne comprends pas pourquoi choisir extensible et maximum est préférable au simple choix d'extensible. »
Par ailleurs, une extension minValueSet parallèle tentait d'établir un plancher pour les liaisons extensibles — si un code de cet ensemble s'applique, vous devez l'utiliser. Mais elle confondait les contraintes des émetteurs avec les obligations des récepteurs, et les validateurs ne pouvaient pas l'appliquer.
Ces deux extensions ne pouvaient exprimer que deux cas d'utilisation étroits, et même ceux-là étaient mal compris.
Le problème des « liaisons multiples souhaitées »
Au même moment, les auteurs d'IG réclamaient sans cesse des liaisons multiples sur un seul élément. Le moteur le plus fréquent était IPS (International Patient Summary), qui devait exprimer un choix de liaisons terminologiques sur un CodeableConcept — différents systèmes de codes pour différentes juridictions. Le seul outil disponible était le slicing — le mécanisme FHIR permettant de dire « cet élément répétable doit avoir des entrées correspondant à des patrons précis ». Appliqué à CodeableConcept.coding, le slicing permettait d'exiger un Coding de SNOMED et un autre de ICD-10. Mais il était complexe à rédiger, difficile à comprendre pour les développeurs, et verbeux dans le rendu des profils.
Comme Grahame Grieve l'a exprimé : « Il y a beaucoup de slicing dans les guides d'implémentation parce que les auteurs veulent dire 'l'un des codes doit provenir du ValueSet X.' C'est l'utilisation la plus courante du slicing, et vous devez le faire parce qu'une liaison s'applique à toutes les répétitions du code. Mais le slicing est difficile pour les développeurs. »
La proposition de Grahame (février 2022)
En février 2022, Grahame Grieve a proposé une nouvelle extension sur ElementDefinition.binding — les liaisons supplémentaires. L'idée centrale : la liaison principale demeure la liaison de conformité (ce que le validateur applique), mais il est possible d'y associer des liaisons supplémentaires ayant des objectifs différents :
Je voudrais définir une extension sur ElementDefinition.binding qui spécifie des liaisons supplémentaires. ElementDefinition.binding est la liaison de conformité : ce que le validateur applique — et il ne peut y en avoir qu'une. Mais en plus, les concepteurs pourront spécifier des liaisons supplémentaires.
Sa liste initiale d'objectifs — conformance, required, recommended, UI, starter, component, minimum, maximum — répondait à toutes les lacunes que la communauté avait tenté de contourner. La motivation :
Dans quelques endroits, nous utilisons extensible+max et nous voulons vraiment un ValueSet de base avec un ValueSet recommandé. Dans quelques endroits, nous utilisons extensible, et nous voulons vraiment un ValueSet de base assez large avec un required — c'est ce que la législation exige pour les nouveaux dossiers.
Rob Hausam a immédiatement vu la valeur pour IPS : « Je conviens que cela semble pouvoir remplacer le slicing sur CodeableConcept.coding... En supposant que tout cela soit vrai, quand pourrons-nous commencer à utiliser ceci dans IPS ? »
Lloyd McKenzie a exprimé des réserves : « En général, si les règles diffèrent selon les contextes, alors vous avez des profils différents. » Mais Grahame a répliqué : « Ce n'est pas rendre service aux utilisateurs que de multiplier les profils qui ne diffèrent que par le contexte d'utilisation et quelques liaisons. »
En avril 2022, l'IG Publisher disposait d'une prise en charge de rendu en version préliminaire, et Grahame a ajouté l'indicateur any — « si any = true, la liaison ne s'applique qu'à l'une des répétitions, et non à toutes. » En août 2022, IPS l'utilisait déjà. La fonctionnalité a été intégrée au scrutin R5 sous la forme de ElementDefinition.binding.additional, et livrée dans R5 (mars 2023) comme élément de première classe — plus comme extension.
Comment ça fonctionne : la sémantique d'abord
Avant d'explorer le catalogue d'objectifs, deux règles fondamentales.
Règle 1 : toutes les liaisons sont en ET. La liaison principale et chaque liaison supplémentaire s'appliquent simultanément. Lloyd McKenzie l'a dit clairement : « Toutes les liaisons s'appliquent toujours. Point final. » Cependant, toutes les liaisons ne mordent pas de la même façon :
- Les liaisons avec un contexte
usagesont ignorées si vous n'êtes pas dans ce contexte - Les objectifs d'orientation (
starter,ui,component,preferred) n'ont aucune valeur de conformité - Les liaisons
currentne s'appliquent qu'aux données saisies depuis la déclaration de conformité — pas aux données historiques - Les liaisons
extensibleont la sortie standard : vous n'êtes pas tenu de vous conformer si aucun code du ValueSet ne s'applique à votre concept
Si vous voulez une sémantique OU (« envoyer un code du ValueSet A ou du ValueSet B »), combinez-les dans un seul ValueSet groupé. Les liaisons supplémentaires ne vous donneront pas le OU.
Pour un CodeableConcept — le type de données FHIR pouvant contenir plusieurs représentations de codes parallèles (Codings) pour le même concept — des liaisons required multiples peuvent signifier que vous avez besoin de plusieurs Codings, chacun satisfaisant une liaison. C'est ainsi que fonctionne « doit envoyer SNOMED ET ICD-10 » sans slicing.
Règle 2 : l'indicateur any modifie la sémantique de répétition. Par défaut, une liaison s'applique à toutes les répétitions d'un élément. Mettre any = true signifie que la liaison est satisfaite si une seule répétition correspond. C'est le mécanisme clé qui remplace les tranches de codage — et comme Lloyd McKenzie l'a noté : « utiliser le slicing pour des liaisons 'et' est désormais considéré comme un antipatron et déconseillé. »
Structure et objectifs
Une liaison supplémentaire ne remplace jamais la liaison principale — elle se superpose à celle-ci. Chacune possède :
| Propriété | Description |
|---|---|
purpose | Pourquoi cette liaison existe (voir les tableaux ci-dessous) |
valueSet | L'URL du ValueSet |
documentation | Markdown expliquant l'utilisation dans le contexte |
shortDoco | Un court résumé en texte brut pour le rendu tabulaire |
usage | UsageContext délimitant par juridiction, domaine ou flux de travail |
any | Si true, satisfaite lorsqu'une seule répétition correspond (par défaut : toutes doivent correspondre) |
Voici à quoi cela ressemble dans une StructureDefinition (notation simplifiée) :
binding:
strength: extensible
valueSet: http://hl7.org/fhir/ValueSet/observation-codes
additional:
- purpose: starter
valueSet: http://example.org/ValueSet/common-lab-codes
documentation: >
A manageable subset of ~200 common laboratory codes
for implementers getting started.
- purpose: current
valueSet: http://example.org/ValueSet/2026-lab-codes
documentation: >
Required for all new observations captured after 2026-01-01.
Legacy data may use codes outside this set.
Les objectifs ont évolué depuis la proposition de Grahame en 2022 (certains ont été renommés, conformance a été supprimé). L'élément purpose a une liaison required — vous ne pouvez utiliser que les codes du ValueSet AdditionalBindingPurposeCodes, aucun objectif personnalisé n'est permis. Voici les codes R5 :
Objectifs de conformité
| Objectif | Signification |
|---|---|
required | L'élément DOIT utiliser un code de ce ValueSet — dans le contexte d'utilisation spécifié |
extensible | Utilisez les codes de ce ValueSet si applicable — dans le contexte d'utilisation spécifié |
current | Les nouveaux dossiers DOIVENT utiliser ce ValueSet. Les données historiques ou provenant de sources externes peuvent utiliser d'autres codes |
Objectifs d'orientation
| Objectif | Signification |
|---|---|
minimum | Toutes les applications conformes doivent accepter ces codes comme valides (obligation d'application, pas contrainte d'instance) |
candidate | Peut remplacer le ValueSet principal dans des situations documentées (p. ex., une juridiction définit un remplacement) |
preferred | Ce ValueSet est préféré dans un contexte donné (la documentation doit expliquer pourquoi) |
ui | Codes suggérés pour la sélection dans l'interface utilisateur |
starter | Un sous-ensemble pratique pour commencer lorsque le ValueSet complet est trop volumineux |
component | Documente comment une partie du ValueSet principal est utilisée (p. ex., par système de codes) |
R6 ajoute current-extensible (sémantique extensible pour les nouvelles données), best-practice (signalé en mode de validation des meilleures pratiques) et open (aucune restriction, à des fins de documentation).
L'objectif maximum existe dans R5 mais est déprécié dans R6. Il était initialement destiné à plafonner les liaisons extensibles, mais sa sémantique n'était pas claire (voir la saga Extensible+Max ci-dessus). Utilisez plutôt required avec un contexte d'utilisation.
À travers les versions FHIR
| Version | Fonctionnement des liaisons supplémentaires |
|---|---|
| R4 et antérieures | Pas natif. Utilisez l'extension additional-binding du Tooling Extensions IG. L'IG Publisher les affiche ; le validateur les prend en charge. Les anciennes extensions maxValueSet et minValueSet fonctionnent encore, mais sont supplantées. |
| R5 | Natif comme ElementDefinition.binding.additional. Prise en charge complète par le validateur. Pas d'élément key — la contrainte des liaisons supplémentaires dans les profils dérivés est limitée. |
| R6 | Natif + élément key pour la contrainte à travers les couches de profils. Nouveaux objectifs : current-extensible, best-practice, open. maximum déprécié. |
Pour les IG R4, les liaisons supplémentaires sont exprimées comme extension sur ElementDefinition.binding :
binding:
strength: extensible
valueSet: http://hl7.org/fhir/ValueSet/observation-codes
extension:
- url: http://hl7.org/fhir/tools/StructureDefinition/additional-binding
extension:
- url: purpose
valueCode: current
- url: valueSet
valueCanonical: http://example.org/ValueSet/2026-codes
- url: documentation
valueMarkdown: Required for new records.
Dans R5+, la même chose s'exprime nativement — aucune enveloppe d'extension n'est nécessaire.
Scénarios
Conformité multijuridictionnelle
Un profil international nécessite des systèmes de codes différents selon les pays — SNOMED CT aux États-Unis, ICD-10-GM en Allemagne. Avant les liaisons supplémentaires, cela impliquait soit des profils distincts par juridiction, soit un slicing complexe. Vous pouvez maintenant l'exprimer dans un seul profil en utilisant required + any: true + usage :
binding:
strength: extensible
valueSet: http://hl7.org/fhir/ValueSet/condition-code
additional:
- purpose: required
valueSet: http://example.org/ValueSet/us-snomed-conditions
any: true
usage:
- code: { code: US, system: urn:iso:std:iso:3166 }
documentation: US jurisdiction — at least one SNOMED CT coding required.
- purpose: required
valueSet: http://example.org/ValueSet/de-icd10gm-conditions
any: true
usage:
- code: { code: DE, system: urn:iso:std:iso:3166 }
documentation: German jurisdiction — at least one ICD-10-GM coding required.
Trois fonctionnalités travaillent ensemble ici : required rend la liaison applicable, any: true signifie « au moins un Coding doit correspondre » (pas tous — vous pouvez donc envoyer d'autres codings en parallèle), et usage délimite chaque liaison à sa juridiction. Un système américain ne voit que l'exigence SNOMED ; un système allemand ne voit que ICD-10-GM. La liaison extensible principale s'applique aux deux.
Migration de données historiques
Un problème courant : un pays passe à un nouveau standard de codification, mais les hôpitaux ont des décennies de données dans l'ancien format. Sans liaisons supplémentaires, vous devez choisir — soit la liaison est assez souple pour les données historiques (et vous perdez la conformité pour les nouvelles données), soit elle est stricte pour les nouvelles données (et les anciens dossiers échouent à la validation).
Les liaisons supplémentaires résolvent ce problème avec current + minimum :
binding:
strength: extensible
valueSet: http://hl7.org/fhir/ValueSet/condition-code
additional:
- purpose: current
valueSet: http://example.org/ValueSet/icd-11-conditions
documentation: >
All new diagnoses captured after 2026-01-01 must use ICD-11.
- purpose: minimum
valueSet: http://example.org/ValueSet/icd-10-icd-11-conditions
documentation: >
Systems must accept both ICD-10 and ICD-11 codes.
La liaison principale reste large (condition-code — extensible). La liaison current dit : « dorénavant, utilisez ICD-11. » La liaison minimum dit : « mais chaque système conforme doit encore accepter ICD-10 dans les données entrantes. » Aucune ne remplace la liaison principale — elles ajoutent de la précision là où l'ancien modèle n'offrait qu'un seul levier.
Liaisons dépendantes de la catégorie (SDOH)
Il s'agit d'un patron réel tiré des profils US Core SDOH. Condition.code est lié à un ValueSet large, mais différentes catégories reçoivent des liaisons plus strictes — si la catégorie est food-insecurity, le code doit provenir du VS SDOH Food Insecurity Diagnoses ; si housing-instability, d'un autre VS. Chaque liaison supplémentaire utilise usage pour délimiter par valeur de catégorie :
# Condition.code
binding:
strength: required
valueSet: http://hl7.org/fhir/us/core/ValueSet/us-core-condition-code
additional:
- purpose: required
valueSet: http://hl7.org/fhir/us/sdoh/ValueSet/food-insecurity-diagnoses
usage:
- code: { code: food-insecurity, system: http://hl7.org/fhir/us/sdoh/CodeSystem/sdoh-category }
documentation: >
When Condition.category = food-insecurity,
code must come from this ValueSet.
- purpose: required
valueSet: http://hl7.org/fhir/us/sdoh/ValueSet/housing-instability-diagnoses
usage:
- code: { code: housing-instability, system: http://hl7.org/fhir/us/sdoh/CodeSystem/sdoh-category }
documentation: >
When Condition.category = housing-instability,
code must come from this ValueSet.
Le contexte usage ici n'est pas une juridiction — c'est une catégorie clinique au sein de la même ressource. Le validateur vérifie : si la Condition a category = food-insecurity, alors la liaison supplémentaire pour la sécurité alimentaire s'applique et code doit provenir de ce ValueSet précis. Si la catégorie ne correspond pas, la liaison est ignorée. Comme Grahame l'a confirmé : « si votre catégorie est l'une des catégories désignées, alors le ValueSet pour cette catégorie s'applique. »
Indications d'interface pour les grands ValueSets
Toutes les liaisons supplémentaires ne concernent pas la conformité. Les objectifs ui et starter n'ont aucune valeur de validation — ils aident les développeurs à créer de meilleures interfaces. Un profil de signes vitaux peut avoir plus de 100 000 codes LOINC dans sa liaison extensible, mais l'interface utilisateur n'en a besoin que d'une poignée :
# Observation.code (vital signs)
binding:
strength: extensible
valueSet: http://hl7.org/fhir/ValueSet/observation-vitalsignresult
additional:
- purpose: starter
valueSet: http://example.org/ValueSet/common-vitals
documentation: >
15 most common vital sign codes. Start here
if you're building a new system.
- purpose: ui
valueSet: http://example.org/ValueSet/vitals-picker
documentation: >
Curated list optimized for dropdown selection.
Not a conformance constraint.
L'objectif starter dit « commencez votre implémentation avec ces codes ». L'objectif ui dit « affichez ces codes dans un sélecteur ». Aucun des deux n'affecte la validation — un système peut envoyer tout code valide selon la liaison extensible principale. Mais ils résolvent un vrai problème : les développeurs qui se retrouvent devant un ValueSet de 100 000 codes sans savoir par où commencer.
Encore en évolution
Le mécanisme est mature, mais la communauté continue de résoudre des cas limites. Aussi récemment qu'à la fin de 2025, Eric Haas a écrit : « Nous avons discuté de ce sujet au WGM, et en tant que concepteur de profils, je suis toujours perplexe quant au fonctionnement prévu des liaisons supplémentaires. » Lui et Gay Dolin créent une matrice de cas d'utilisation explicites avec des exemples pour le FHIR Guidance IG. Les principaux aspects en cours d'affinement :
- Liaisons conditionnelles — utiliser
usage(UsageContext) pour délimiter les liaisons par juridiction ou flux de travail est puissant mais complexe en pratique (66 messages et en progression). - Comportement du validateur — la façon dont les violations sont signalées varie selon l'objectif :
requiredproduit des erreurs, les objectifs d'orientation commestarteretuisont purement informatifs.
Références et discussions communautaires
Spécification :
- ElementDefinition.binding.additional — définition formelle
- Additional Binding Purpose Codes — tous les codes d'objectif avec définitions
- Terminologies: Binding Strengths — fonctionnement des forces avec les liaisons supplémentaires
- Binding Examples — exemples concrets
- Tooling Extensions IG — extension de rétrocompatibilité pour R4
Communauté (chat.fhir.org) :
- Extension for additional bindings — la proposition originale de 2022 par Grahame Grieve (49 messages)
- Implementing Additional Bindings for each purpose — sémantique ET vs OU, matrice de cas d'utilisation (27 messages)
- Conditional additional bindings — délimitation par UsageContext (66 messages)
- Extensible+Max — le patron antérieur à R5 (182 messages)
- Modifications to ElementDefinition — engagement formel R5 (111 messages)
Voir aussi : Catégories résiduelles en Terminology FHIR.

![Terminology is fun: CodeableConcept.coding[]](/assets/images/articles/horizontal-5.avif?v=2ef8.mrd)

