---
{
  "title": "Liaisons sans limites",
  "description": "Comment les liaisons supplémentaires de FHIR R5 résolvent les limites du modèle classique à une seule liaison par élément, grâce à des contraintes terminologiques en couches.",
  "date": "2026-03-24",
  "author": "Nikolai Ryzhikov",
  "reading-time": "14 min read",
  "tags": ["FHIR Standard", "FHIR Profiling", "Terminology"],
  "tldr": "Les liaisons supplémentaires — introduites dans FHIR R5 — permettent d'associer plusieurs contraintes terminologiques à un seul élément, chacune avec son propre objectif : exiger des codes précis pour les nouvelles données, suggérer un sous-ensemble de départ, fournir des indications pour l'interface utilisateur, ou appliquer des règles propres à une juridiction. Elles se superposent à la liaison principale sans jamais la remplacer."
}
---
## 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](http://hl7.org/fhir/R5/valueset-administrative-gender.html) 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`](https://hl7.org/fhir/R4/extension-elementdefinition-maxvalueset.html), introduite dans [STU3](http://hl7.org/fhir/STU3/extension-elementdefinition-maxvalueset.html) 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](https://chat.fhir.org/#narrow/stream/argonaut/topic/Extensible%2BMax) : 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`](https://hl7.org/fhir/R4/extension-elementdefinition-minvalueset.html) 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](/blog/how-to-create-a-fhir-implementation-guide) réclamaient sans cesse des **liaisons multiples** sur un seul élément. Le moteur le plus fréquent était [IPS (International Patient Summary)](http://hl7.org/fhir/uv/ips/), 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](/articles/grahame-grieve-interview-future-of-fhir-in-2025) [l'a exprimé](https://chat.fhir.org/#narrow/stream/terminology/topic/Extension%20for%20additional%20bindings) : « 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é](https://chat.fhir.org/#narrow/stream/terminology/topic/Extension%20for%20additional%20bindings) 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à](http://build.fhir.org/ig/HL7/fhir-ips/StructureDefinition-Immunization-uv-ips.html). La fonctionnalité a été [intégrée au scrutin R5](https://chat.fhir.org/#narrow/stream/fhir.2Finfrastructure-wg/topic/Modifications%20to%20ElementDefinition) 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](https://chat.fhir.org/#narrow/stream/IG.20creation/topic/Implementiing%20Additional%20Bindings%20for%20each%20purpose%20unclear) : « 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 `usage` sont **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 `current` ne s'appliquent qu'aux données saisies **depuis la déclaration de conformité** — pas aux données historiques
- Les liaisons `extensible` ont 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](http://hl7.org/fhir/R5/datatypes.html#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é](https://chat.fhir.org/#narrow/stream/IG.20creation/topic/Implementiing%20Additional%20Bindings%20for%20each%20purpose%20unclear) : « 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](http://hl7.org/fhir/R5/elementdefinition-definitions.html#ElementDefinition.binding.additional) 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](http://hl7.org/fhir/R5/metadatatypes.html#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) :

```yaml
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](http://hl7.org/fhir/R5/valueset-additional-binding-purpose.html), 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).

{% hint style="info" %}
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.
{% endhint %}

## À travers les versions FHIR

| Version | Fonctionnement des liaisons supplémentaires |
|---|---|
| **R4 et antérieures** | Pas natif. Utilisez l'[extension additional-binding](https://hl7.org/fhir/tools/StructureDefinition-additional-binding.html) 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` :

```yaml
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` :

```yaml
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` :

```yaml
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](https://chat.fhir.org/#narrow/stream/IG.20creation/topic/Context%20Dependent%20Additional%20Bindings). `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 :

```yaml
# 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é](https://chat.fhir.org/#narrow/stream/IG.20creation/topic/Context%20Dependent%20Additional%20Bindings) : « 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 :

```yaml
# 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](https://chat.fhir.org/#narrow/stream/IG.20creation/topic/Implementiing%20Additional%20Bindings%20for%20each%20purpose%20unclear) : « 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](https://build.fhir.org/ig/FHIR/ig-guidance/). 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](https://chat.fhir.org/#narrow/stream/implementers/topic/Conditional%20additional%20bindings) (66 messages et en progression).
- **Comportement du validateur** — la façon dont les violations sont signalées varie selon l'objectif : `required` produit des erreurs, les objectifs d'orientation comme `starter` et `ui` sont purement informatifs.

## Références et discussions communautaires

**Spécification :**

- [ElementDefinition.binding.additional](http://hl7.org/fhir/R5/elementdefinition-definitions.html#ElementDefinition.binding.additional) — définition formelle
- [Additional Binding Purpose Codes](http://hl7.org/fhir/R5/codesystem-additional-binding-purpose.html) — tous les codes d'objectif avec définitions
- [Terminologies: Binding Strengths](https://www.hl7.org/fhir/terminologies.html#strength) — fonctionnement des forces avec les liaisons supplémentaires
- [Binding Examples](http://hl7.org/fhir/terminologies-binding-examples.html) — exemples concrets
- [Tooling Extensions IG](https://hl7.org/fhir/tools/StructureDefinition-additional-binding.html) — extension de rétrocompatibilité pour R4

**Communauté ([chat.fhir.org](https://chat.fhir.org)) :**

- [Extension for additional bindings](https://chat.fhir.org/#narrow/stream/terminology/topic/Extension%20for%20additional%20bindings) — la proposition originale de 2022 par Grahame Grieve (49 messages)
- [Implementing Additional Bindings for each purpose](https://chat.fhir.org/#narrow/stream/IG.20creation/topic/Implementiing%20Additional%20Bindings%20for%20each%20purpose%20unclear) — sémantique ET vs OU, matrice de cas d'utilisation (27 messages)
- [Conditional additional bindings](https://chat.fhir.org/#narrow/stream/implementers/topic/Conditional%20additional%20bindings) — délimitation par UsageContext (66 messages)
- [Extensible+Max](https://chat.fhir.org/#narrow/stream/argonaut/topic/Extensible%2BMax) — le patron antérieur à R5 (182 messages)
- [Modifications to ElementDefinition](https://chat.fhir.org/#narrow/stream/fhir.2Finfrastructure-wg/topic/Modifications%20to%20ElementDefinition) — engagement formel R5 (111 messages)

Voir aussi : [Catégories résiduelles en Terminology FHIR](/blog/residual-categories-in-fhir-terminology).