FHIR Profiling Guidelines: verschil tussen versies

Uit informatiestandaarden
Ga naar: navigatie, zoeken
k (Clarification of the purpose field)
(Clarification of element name)
Regel 164: Regel 164:
* We only profile elements, cardinalities and bindings that require profiling. We leave other elements, cardinalities and bindings as-is (see [[#Open_vs._Closed_Modeling]])
* We only profile elements, cardinalities and bindings that require profiling. We leave other elements, cardinalities and bindings as-is (see [[#Open_vs._Closed_Modeling]])
* For elements that map to Health and Care Information Models (HCIM):
* For elements that map to Health and Care Information Models (HCIM):
** We copy the name from the HCIM element into the profile element.short
** We copy the name from the HCIM element into the profile element.short (in elements that refer to other zibs, the name is built up like ''<<ElementName::ReferenceZibName>>'', but we only use the part before the double colons)
** The HCIM concept description is placed in the profile element.definition
** The HCIM concept description is placed in the profile element.definition
** The HCIM Dutch concept name is placed in the profile element.alias
** The HCIM Dutch concept name is placed in the profile element.alias

Versie van 14 mei 2019 om 13:27


FHIR requires profiling. To do profiling in a comparable way we need conventions. This page lays out these conventions.

The created profiles are generally based on the Health and Care Information models (HCIM) defined by the program ‘Registratie aan de bron’ (Data capture at the point of Care) for the Netherlands. In the Netherlands, these models are more commonly known by the name zorginformatiebouwstenen or ZIB's. In this text, we make use of the HCIM abbreviation. The section Associating functional definition to StructureDefinition provides more information regarding these information models.

Canonical URL

Any conformance resource needs a canonical URL. This preferably leads somewhere but does not have to be processable. Canonical URL's are about the identity of artifacts, not necessarily about retrieval location. URIs for the latter (for artifacts living in ART-DECOR) are described in ART-DECOR FHIR_URIs.

For Nictiz profiles we SHALL use the following structure:

  • For HCIM related profiles (this should be the majority of profiles):
    http://[domain]/fhir/StructureDefinition/zib-[English hcim name]
  • For extensions pertaining to 1 HCIM:
    http://[domain]/fhir/StructureDefinition/zib-[English hcim name]-[English hcim concept name]
  • For extensions pertaining to multiple HCIM:
  • For other profiles:
  • For value sets related to HCIMs:
    http://decor.nictiz.nl/fhir/ValueSet/[value set OID]--[effective date as yyyymmddhhmmss]


  • [domain] is "nictiz.nl"
  • [project] is preferably the same as its matching ART-DECOR project prefix

This convention aligns with international initiatives such as DAF and QiCore and has been confirmed/advised by Grahame Grieve.

Versioning intro

The HL7® FHIR® specification specifies a lot of things related to versions. This text aims to stay aligned with the latest insights. Readers should first get acquainted with the core FHIR specification before reading here: http://hl7.org/fhir/versions.html

Versions of the profiles

Versions of the profiles may occur for any of the following reasons:

  • New releases of the underlying HCIMs are normally followed by an update to the representing profiles
  • Identified issues in existing profiles may require an update
  • HL7® FHIR® updates may lead to an update of the profiles. We do not automatically follow every FHIR version as it is released

Version updates first and foremost affects the version element found in all conformance resources (profiles, value sets, extensions, search parameter, operation definition etc.). The update normally does not affect the canonical URI of the conformance resource. Conformance resources create a web of interrelated artifacts. Any resource that references another resource, e.g. Patient referencing Practitioner for the general practitioner, normally does so without a version indicator (uri|version). This means that any reference points dynamically to 'the latest version' of the artifact. If you were to build a consistent set of versions you would need to add the version to any reference in the set of conformance resources and update the full set after any updating any particular part.

Around the advent of FHIR R4, the follow up of STU3, there will be a new versioning layer that allows packaging of profiles into a consistent set without affecting the profiles itself. The packaging mechanism will be tested in May 2018, and should greatly simplify specification and implementation of versions.

Profiles with versioned references vs Packaged versions of profiles

Versions in instances

To understand how instances of resources are interpreted by a receiving server we should look at two things:

  • The indicator for the profile that the sender added to the instance (if any). This indicator would be in the Resource.meta.profile element and may include a version, e.g.
    <profile value="http://fhir.nl/fhir/StructureDefinition/nl-core-patient"/>
  • The profile (versions) that the server defaults to in the absence of a profile indicator in the instance

If the server does not support the profile (version) as indicated in the instance it may do any of the following things. See also the relevant section in the FHIR specification.

  1. Try to support the instance based on what it can support. This may lead to ignoring any element it doesn't know, except for modifierElements. If modifier elements are encountered, the instance should be rejected
  2. Reject the instance

Note: as specified in the core FHIR specification, the server SHALL use its CapabilityStatement to indicate its behavior around unsupported elements (ignore or reject)

Associating functional definition to StructureDefinition

Any StructureDefinition that profiles a Resource does so because there is some kind of logical definition dictating how. These functional definitions are known as Clinical Building Blocks, Health and Care Information Models or in Dutch Zorginformatiebouwstenen or zibs. Profiles SHALL have a traceable relationship with their functional counterpart(s).

The FHIR specification contains several solutions for this problem, ConceptMap (>=STU1), StructureMap (>=STU3), ElementDefinition.mapping. Neither of these solutions are mature and cover our use case.

  • ConceptMap: works best for value sets and codes.
  • StructureMap: overcomplicated and unclear how to apply and whether or not this has a future.
  • ElementDefinition.mapping: is a free text mapping inside the profile. This means we cannot add mappings to profiles from third parties without updating their resource.

Current implementation

We use the mapping elements in profiles to map functional elements to resource elements. When slicing, the mapping is made on the content of the slice, not the slice itself (see also #Placing-Info).

Functional elements are referenced based on their mnemonic id in the HCIM, e.g. NL-CM:9.6.19936. The mapping shall resolve to the English page on zibs.nl:

       <identity value="hcim-medicationagreement-v1.0-2017EN" />
       <uri value="https://zibs.nl/wiki/MedicationAgreement-v1.0(2017EN)" />
       <name value="HCIM MedicationAgreement-v1.0(2017EN)" />


   <element id="MedicationRequest.extension:usageDuration">
       <path value="MedicationRequest.extension" />
           <identity value="hcim-medicationagreement-v1.0-2017EN" />
           <map value="NL-CM:9.6.19936" />

Proposed way forward

  1. The functional definitions live in ART-DECOR and every concept in this functional definition has a versioned id.
  2. The technical FHIR profile elements we want to map to have an optional @id attribute, but according to Tracker#9843 it is a required item for profiles (StructureDefinition)
  3. In our own profiles we can make sure we populate this Element/@id and associate the functional concept on id / id basis. We found that DAF Profiles populate these ids as well.
    • Example: <element id="Patient:DAF-Patient.extension:race">...</element>
    • Example: <element id="2.16.840.1.113883.3.1937.">
  4. In profiles we reference from third parties that do not have this Element/@id populated we need a less precise method. We will deal with that when we need to.

Practical guidelines

File names

  • For profiles: <<the final part of the canonical URI>>.xml
  • For valuesets: <<Valueset.name>>-<<Valueset.id>>.xml

Profile meta data

  • URL: see above
  • Resource ID: final part of the canonical URI
  • Name: final part of the canonical URI (without hyphens, capitalized)
  • Description:
    • A(n) <<enter resource type>> resource as defined by the Dutch Health and Care Information models (Dutch: Zorginformatiebouwsteen or ZIB) <<Zorginformatiebouwsteen name>> <<version>> <<release>>
    • Followed by the 'Concep' section from the HCIM
  • Version: as applicable to the profile, not the HCIM it refers to
  • Date: n/a
  • Lifecycle status: as applicable (normally draft or active)
  • Experimental: normally false or null
  • Title: final part of the canonical URI (without hyphens, with 'zib' replaced by 'HCIM')
  • Purpose:
    • 'Purpose' section from HCIM
    • If needed: a discussion of where this profile fits in the workflow and why this resource was chosen (separated using a header in Markdown)
  • Copyright: CC0
  • Publisher: Nictiz
  • Contact information: n/a
  • Use context: n/a
  • Keywords: n/a
  • Mappings: uri to the version of the HCIM specification (see #Associating_functional_definition_to_StructureDefinition)
        <identity value="hcim-contactperson-v3.1-2017EN"/>
        <uri value="https://zibs.nl/wiki/ContactPerson-v3.1(2017EN)"/>
        <name value="HCIM ContactPerson-v3.1(2017EN)"/>
  • Identifiers: n/a
  • Meta data: tbd
  • Implicit rules (URI): n/a
  • Language: n/a (most content is en-US from the core, some is nl-NL from the HCIMs)
  • Kind: n/a (auto handled by Forge)
  • Type: n/a (auto handled by Forge based on selection at creation time)
  • Abstract: false
  • Base definition: n/a (auto handled by Forge based on selection at creation time)
  • FHIR version: n/a (auto handled by Forge based on selection at creation time) - initially 3.0.1 STU3

Mapping DefinitionCodes

Sometimes a FHIR element is equivalent to the HCIM concept (like a comment and a Resource.comment element), but if not, a code (usually SNOMED or LOINC) needs to be added to the FHIR profile to provide the proper definition. This is for example the case in Observation, where the root concept of the observation is unknown unless it is defined by the .code element, and where every .component needs to be defined by an individual .code element. Usually, the concepts for these elements are provided by the HCIMs (as DefinitionCode).

We map these DefinitionCodes from the HCIM in an extendable way onto the profile, by using a slice where at least the DefinitionCode is required. In practice this will look like:

FHIR path Remark Cardinality
.code 1..1
.coding sliced on value/code 1..*
slice for concept named after the concept name 1..1
.system code system from HCIM as fixedValue 1..1
.code code from HCIM as fixedValue 1..1
.display display value defined in the code system as defaultValue 0..1

Binding HCIM defined ValueSets

  • the ValueSet can be obtained in FHIR 3.0 format from ART-DECOR (see #File_names for file naming conventions)
  • the reference URL can be obtained from the <<ValueSet.url>> element in this file
  • we use binding strength "extensible".
  • the <<binding.description>> value is set to <<ValueSet.name>>


  • We only profile elements, cardinalities and bindings that require profiling. We leave other elements, cardinalities and bindings as-is (see #Open_vs._Closed_Modeling)
  • For elements that map to Health and Care Information Models (HCIM):
    • We copy the name from the HCIM element into the profile element.short (in elements that refer to other zibs, the name is built up like <<ElementName::ReferenceZibName>>, but we only use the part before the double colons)
    • The HCIM concept description is placed in the profile element.definition
    • The HCIM Dutch concept name is placed in the profile element.alias
    • Note: as a rule of thumb, we place this info 'as close as possible' to the elements that actually represent the data. For example: when slicing, the texts are placed on the slice content, not the slice itself. Similarly, in concept containers like Observation.component, this info is placed on the .valueXXX elements. This is also true for the HCIM mappings.
  • Slices get an UpperCamelCased name based on the HCIM element name.
  • New elements defined through extensions get a lowerCamelCased name based on the HCIM element name.
  • When adding invariants we use "hcim-[hcim-name]-[number]" as a key. Example: hcim-alert-1
  • FHIR URI Strategy (draft document with potentially good info)
  • For FHIR base resource elements with datatype code and binding required it may be that the HCIM has other/additional codes to specialize the FHIR codes. To conform to FHIR and the HCIM we will use the FHIR required element and binding and specify the mapping. We will use 1 extension to cover this use case.
    • Extension URI http://nictiz.nl/fhir/StructureDefinition/code-specification
    • The extension is of datatype CodeableConcept which also support text as a fallback
    • The extension receives its ValueSet binding in the context of the profile element and does not have a binding internally
    • The extension is only required to be present when the extension actually holds a specialization, e.g. CRITH + fatal. It is optional when the mapping is equal
    • The mapping shall be documented in a ConceptMap
    • Example AllergyIntolerance.criticality
CRITL medium
CRITH high
CRITH fatal

Open vs. Closed Modeling

× Open Closed
Pros - Forward compatibility

- Modelers don't have to think about what you shouldn't support, only what must be supported

- Implementers can fit more data, even if it's not in specified explicitly bu the profile

- Implementers, don't have to support all elements that maybe, someday could be used, according to the model

- Model becomes more specific

- Model becomes smaller and more straightforward

- More implementer feedback, about elements they want to support, but currently can't


- Implementers, have to support all optional elements that maybe, someday could be used, according to the model - Model becomes more vague,

- Model becomes larger and less straightforward about what should actually be supported, and what can optionally be supported

- Less implementer feedback: elements they want to send can be easier 'hacked' in a not yet explicitly specified element. Model won't be improved.

- More versions of models, after more elements have to be supported

- No forward compatibility, only backwards

- Implementers have to wait for a new version of the model, if they want to support elements, that are currently not in scope.

We have chosen for "open" modeling for the HCIMs, since they are very general and not meant for one specific use case. Excluding unspecified elements here is not an option, since we expect derived profiles for more specific use cases that may need those elements.

Cardinality/conformance mapping table

Cardinality applies to the number of occurrences that an element MAY/SHOULD/SHALL have. Minimum cardinality is integer 0. Maximum cardinality is "n" or "*" (exact character depends on tooling). If the minimum cardinality is higher than 0, then an element has to be present.

Conformance applies to what a system MAY/SHOULD/SHALL support. When data for an element is missing, e.g. because it is not applicable, then the element may be absent, but when conformance MustSupport is active, then a conformant application SHALL support it. Contrary to V3, there is no concept of NullFlavor in FHIR, so whenever an element is 1..1 in FHIR, there is no escape through NullFlavor: a value SHALL be present.

Reference: ElementDefinition.mustSupport

This poses a need for a mapping table from cardinality/conformance in HCIMs versus that in profiles.

0..1 0..1
0..1 C 0..1
0..1 R 0..1 mustSupport='true'
0..* 0..*
0..* C 0..*
0..* R 0..* mustSupport='true'
1..1 0..1
1..1 C 0..1
1..1 R 0..1 mustSupport='true'
1..1 M 1..1 mustSupport='true'
1..* 0..*
1..* C 0..*
1..* R 0..* mustSupport='true'
1..* M 1..* mustSupport='true'

Constraining references

HCIMs might have have connections to other HCIMs. Example: a MedicationAgreement might have a Prescriber relationship defined using a HealthProfessional which is mapped to a FHIR MedicationRequest.requester as Reference(Practitioner). The FHIR MedicationRequest however, defines more types: Reference(Practitioner | PractitionerRole | Organization | Patient | RelatedPerson | Device). The closed world model would mandate that the profile only marks Practitioner for use. The open world model would mandate that the profile describes that for a HealthProfessional you need the Practitioner without omitting the other choices.

For general purpose profiles, suitable for further constraining we use open world profiling meaning that we do not constrain the choices of references into just the types that the HCIM requires. We only constrain the generic resource reference to the generic profile(s) for that resource. For Practitioner this would be the nl-core-practitioner. If deemed relevant a second layer of derived profile(s) could be created to tailor the generic profile for a specific use case using closed world modeling.

Data type mapping table

DECOR defines a set of data types. In most cases, the mapping to FHIR is straightforward, though there are a number of cases which are not as clear-cut. When defining extensions, or specifying the datatype of an Observation or Questionnaire.item in FHIR, a mapping to the relevant FHIR datatype needs to be done. The table below shows a mapping for datatypes in HCIMs versus those in profiles.

INT count Count or integer Count in FHIR is derived from Quantity, this is appropriate for observations, such a a count of red blood cells in a specimen. Count in FHIR is a Quantity with code="1" (for units). If this is not appropriate, use integer.
BL boolean boolean
ED blob base64Binary
CD code CodeableConcept or coding or code In general, CodeableConcept will be the right choice. See Using Codes in Resources for details.
ANY complex BackboneElement 'complex' is data which is not further defined in DECOR, and thus cannot be translated.
- currency Money Does not have a HCIM counterpart currenty. Theoretically this could be MO
- date date Does not have a HCIM counterpart currently. Closest counterpart could be TS
TS datetime dateTime
- decimal decimal Does not have a HCIM counterpart currently. Theoeratically this could be REAL
- duration Duration Does not have a HCIM counterpart currently. Closest counterpart could be PQ
II identifier Identifier
CO ordinal CodeableConcept or coding or code See Using Codes in Resources for details.
ST string string
- ratio Ratio Does not have a HCIM counterpart currently. Closest counterpart could be RTO
- text string Does not have a HCIM counterpart currently.
PQ quantity Quantity

Translating DECOR to FHIR

Status: proposal

Quite often we will populate FHIR artifacts from DECOR artifacts. In such cases, FHIR identification must be derived from DECOR identification.

DECOR uses the attributes id and effectiveDate to identify concepts, datasets, transactions, valueSets and templates. The artifacts with the same id but different effectiveDates are subsequent versions of the same artifact (though artifacts can also get a new id for a new version, such as when a new dataset is derived from an older one).

In FHIR, every resource can have an id, which is the "logical id" of the resource. This id never changes once assigned, like DECOR id and effectiveDate. Resources usually have an URL too, which also identifies the resource, but should be resolvable. The URL can contain the id.

The following ART-DECOR artifacts map to FHIR artifacts:

DECOR artifact FHIR artifact FHIR identifier system Notes
concept DataElement http://art-decor.org/ns/oids/de DataElement is a wrapper around a FHIR element (based on ElementDefinition). A FHIR element is not serializable independently, but is wrapped in a StructureDefinition or DataElement.
Logical Model http://art-decor.org/ns/oids/sd A Logical Model is a StructureDefinition without base resource. FHIR uses this to capture user requirements.
valueSet ValueSet http://art-decor.org/ns/oids/vs

The following FHIR attributes are constructed in the following way, when generated from ART-DECOR. Non-digits are stripped from the timestamp in @effectiveDate because they violate the FHIR rules for id.

FHIR artifact derivation from DECOR
FHIR id @id + '--' + @effectiveDate
FHIR identifier system See above
FHIR identifier value @id
FHIR version @effectiveDate
FHIR status See below

Status is translated from DECOR to FHIR:

DECOR status FHIR status
new draft
draft draft
pending draft
active active
review draft
cancelled retired
rejected retired
deprecated retired
default is 'draft'