PATIENT ADMINISTRTAION (PA) Workgroup Development Draft

1.23.0 Using Codes in Resources

Many elements in the FHIR resources have a coded value: some fixed string (a sequence of characters) assigned elsewhere that identifies some defined "concept". The sequence of characters and its meaning may be defined in one of several places:

  • As one of a set of fixed values defined in this specification
  • In an internet RFC (e.g. mime type, language)
  • An HL7 specification (v3 code system, or v2 table)
  • Some external terminology or ontology such as LOINC, or SNOMED CT
  • A locally maintained dictionary, look up table or enumeration in an application

All of these kinds of ways of defining codes are collectively called "code systems". This list is far from complete; there are many ways to define code systems, and they vary widely in sophistication and size.

Throughout this specification, coded values are always treated as a pair composed of "system" and "code", where the system is a URL that identifies the code system that defines the codes.

The FHIR framework for using coded values is based on the fundamental framework defined in section 5 of the HL7 v3 Core Principles document.

When codes are carried in resources, one of 4 different data types is used:

codeThe instance represents the code only. The system is implicit - it is defined as part of the definition of the element, and not carried in the instance.
CodingA data type that has a code and a system element that identifies where the definition of the code comes from
CodeableConceptA type that represents a concept by plain text and/or one or more Codings
QuantitySpecial case: has system and code elements for carrying a code for the type of unit

Note: System values are always case sensitive. Different code systems make their own rules as to whether the codes they define are case sensitive or not. Note that all the codes defined by FHIR itself are case sensitive and SHALL be used in the provided case (usually, but not always, lowercase).

1.23.0.0.1 Binding String Values

In a few special cases, humans customarily use codes directly for elements that have type "string". A typical case is codes for states, adnd there are several places where a URIs must come from a set of controlled values. An element of type string or uri can also be bound to a value set. When a string or uri is bound to a value set, the value property SHALL contain the code specified by the value set, and the system and display values are ignored.

1.23.0.1 Controlling the use of Coded Values

The set of coded values that is allowed to be used in an element of one of these 4 data types is known as a "value set". Anywhere these data types are used, the specification "binds" a value set to the element.

The difference between a code system and a value set is an important distinction that is often missed by implementers, since the difference is often overlooked in system design. For instance, it's not unusual to see a system table that is a mixed list of codes, containing some LOINC codes and also some additional in-house codes. Quite often, there is no explicit differentiation between them; only the fact that a code happens to look like a LOINC code betrays its origin.

For data exchange, on the other hand, explicitly tracking the source of the code is both important and necessary. In order to do this, each code system that defines codes is assigned a URL that identifies it, and all the codes it defines are actually a pair ("Code Pair": a name with a namespace). So in the case of this mixed list example from the previous paragraph, there is two code systems: LOINC (http://loinc.org) and a local one (let's say it has been given the URL: http://example.com/codesystems/additional-test-codes). The system table is a single value set (a set of Code Pairs) that includes codes from each of those two namespaces. The value set itself is given its own URL as an identifier (e.g. "http://example.com/fhir/ValueSet/test-codes)") - this identifies the set of Code Pairs, but is never used as the namespace in a actual code pair, or in an instance. In FHIR, Code Pairs are always represented as "code" and "system", except for the simple data type "code" data type where the namespace (e.g. the system element/property) is fixed in the schema and not represented explicitly.

This means that in FHIR, the URL in a system element is always a reference to a code system, not to a value set.

When an element is bound to a value set, the binding has these properties:

NameA descriptive name used when presenting information about the binding
StrengthHow the binding should be understood - see below
ReferenceA URL that defines the value set. Usually, this is a direct reference to a ValueSet resource, but can be a more indirect reference, where the value set is inferred
DescriptionA text description of the use of the codes. If there is no reference, this must be populated. When there is a reference, this can be used to make additional notes about the use and implementation of the value set

In the FHIR declarative datatypes, a binding is always represented using an ElementDefinition,binding.

1.23.0.1.1 Value Set References

There are a number of places in the specification where value sets are referenced in order to bind a coded value to a value set:

ElementDefinition.binding.valueSet[x]Used to bind a defined element to a value set
ConceptMap.source[x] and .target[x]used to indicate the scope of the mapping in the Concept Map - from one value set to another
Questionnaire.group.question.optionsIndicates that answers to a set of questions come from a value set
ValueSet.compose.importThe content of a value set includes the content in the imported value set too
ValueSet Reference ExtensionIndicates that a particular coded value was chosen from the specified value set

There are two types of value set references in this list, direct and logical.

1.23.0.1.1.1 Direct Value Set references

A direct value set reference has the type Reference, and refers directly to a ValueSet based on a URL, usually to a terminology server running a FHIR RESTful API. When accessing a value set based on this kind of reference, a system should access the URL directly (after converting a relative reference to an absolute reference according to the local context). If this process fails, the system is unable to resolve the value set and must handle the error appropriately.

Example:

GET fhir/Questionnaire/234

<Questionnaire>
  ...
  <question>
    <options>
      <reference value="ValueSet/234234"/>
    </options>
  </question>
  ....
</Questionnaire>

This specifies that the values for a particular questionnaire come from the ValueSet with id 234234 on the same FHIR end-point. To resolve this, the system would GET fhir/ValueSet/234234

Typically, a direct reference like this is good for in-process references, in closed or carefully managed eco-systems. In a more general context, these references tend to be fragile over time because web URLs - including RESTful API URLS - are easily reassigned. For this reason, systems are encouraged to use logical value set references.

1.23.0.1.1.2 Logical Value Set references

A logical value set reference has the type uri, where an absolute URI is provided that matches the one in ValueSet.url. The value set URL can - and is preferred to be - a web address that actually resolves directly to a fixed web address that serves as the authoritative source for that value set. Alternatively, the system can query its terminology server(s) to resolve a value set with that URL as its identity.

Example:

<StructureDefinition>
  ...
  <element>
    ...
    <binding>
      ...
      <valueSetUri value="http://hl7.org/fhir/vs/clinical-findings"/>
    </binding>
    ...
  </element>
  ....
</StructureDefinition>

This specifies that the element is bound to the value set with a Value.url of http://hl7.org/fhir/vs/clinical-findings. One way to accees this value set is to try GET http://hl7.org/fhir/vs/clinical-findings - which works, for this value set - http://hl7.org/fhir/vs/clinical-findings returns the authoritative value set for this URL.

Alternatively, the value set could be resolved using a local terminology server. If that's running a FHIR Terminology Server, then this would work like this:

GET fhir/ValueSet?url=http://hl7.org/fhir/vs/clinical-findings

if the terminology server knows the value set, then it will return the value set. If the URL doesn't resolve to an authoritative value set, and the terminology server(s) don't know the value set, the system is unable to resolve the value set and must handle the error appropriately.

The value set URL is allowed to be a URI such as a UUID (e.g. urn:uuid:c0e0d027-1250-4278-8f44-33a49dc67916). These value sets can never be accessed directly, and must come from a terminology server. Note that this specification defines many value sets that have a logical URL that is not resolvable (examples for SNOMED CT, RxNorm, LOINC)

Using a logical reference which is a direct reference to the authoritative value set is the easiest and most reliable approach. However this requires suitable hosting arrangements, and cannot always be guaranteed, so it is not required.

Version specific Logical References

A value set has a two part identifier: a url, and a version. Some value sets only ever have a single 'version'; a revision of the value set contents will cause a new url to be assigned. Others, however, maintain the same URL, and change the version. A terminology server may have multiple value sets for the same ValueSet.url with different versions.

To be precise about which version of a value set is being referred to in a value set reference, append the the version to the logical url like this:

<valueSetUri value="http://hl7.org/fhir/vs/clinical-findings?version=0.8"/>

This is a version specific reference to a value set. Searching for this on a terminology server would look like this:

GET fhir/ValueSet?url=http://hl7.org/fhir/vs/clinical-findings&version=0.8

Note that if a value set reference does not have a version, and the server finds multiple versions for the value set, the system using the value set should pick the latest version of the value set and use that.

1.23.0.1.1.3 Unbound

Note that as a matter of ongoing development, a few elements that have coded data types are not bound to any value set at all. Bindings are to be provided for these elements.

1.23.0.2 Binding Strengths

Almost all of the elements that have a coded data type are bound to a value set. The bindings are associated with various degrees of flexibility as to how closely the value set should be followed:

requiredTo be conformant, instances of this element SHALL include a code from the specified value set
extensibleTo be conformant, instances of this element must include a code from the specified value set if any of the codes within the value set can apply to the concept being communicated. If the valueset does not cover the concept (based on human review), alternate codings (or, data type allowing, text) may be included instead.
preferredInstances are encouraged, to draw from the specified codes for interoperability purposes but are not required to do so to be considered conformant
exampleInstances are not expected or even encouraged to draw from the specified value set. The value set merely provides examples of the types of concepts intended to be included

Irrespective of the binding strength, when a StructureDefinition is used to describe local usage, it can bind the element to a different value set in order to be much more precise about exactly which coded values can be used for these elements, and/or increase the strength of the binding. There are different rules for this, depending on the binding strength, as discussed below. Generally it is expected that jurisdictions, projects and vendors will work together to choose actual working value sets.

1.23.0.2.1 Required

To be conformant, instances of this element SHALL include a code from the specified value set..

In the standard, this is generally used for elements where the value needs to be strictly controlled so that everyone can interpret it with confidence. Generally, this is used for elements with type code:

  • the element is bound to a value set that contains a list of distinct codes with a specified system (and version, where required)
  • the element is bound to some external standard that defines the set of valid codes that can be used (typical examples of references are Mime Types, Language Codes, UCUM, etc.)

The other place where this is used is when profiling resources, and there is agreement within a particular context of use that a particular set of codes are the only ones that can be used. In these cases, the data type SHALL contain one of the values in the value set. If the data type is CodeableConcept, then one of the coding valuws SHALL be from the specified value set. Text can be provided as well, and is always recommended, but is not an acceptible substitute for the required code.

Note the following additional rules about required bindings when used with the code data type:

  • Where the value set is defined by FHIR, the list of allowed codes will be fixed in the XML schema
  • Comparison between codes is always case sensitive for codes unless the codes are defined by reference, and the referenced specification clearly states otherwise
  • The list of codes that can be used can only be extended in subsequent releases of the FHIR specification

When an element is bound to a required value set, derived profiles may state rules on which codes can be used, but cannot define new or additional codes for these elements.

1.23.0.2.2 Extensible

To be conformant, instances of this element SHALL include a code from the specified value set if any of the codes within the value set can apply to the concept being communicated. If the valueset does not cover the concept (based on human review), an alternate system.code may be used instead.

If the data type is CodeableConcept, then one of the coding values SHALL be from the specified value set if a code applies, but if no suitable code can be found, text may provided in its place.

Extensible bindings are used when there is consensus at the specification or profiling level about the coded values that should be used, but it is impossible to create a bounded list of codes that a known to cover all use cases, including one that are yet to arise.

When an element is bound to an extensible value set, derived profiles may state rules on which codes can be used, but cannot define new or additional codes for these elements unless no codes with appropriate meanings are found in the base value set.

1.23.0.2.3 Preferred

Instances are encouraged to draw from the specified codes for interoperability purposes but are not required to do so to be considered conformant.

If the data type is CodeableConcept, then one of the coding values SHOULD be from the specified value set, but another code and/or text can be used in its place.

Preferred bindings are used when there is consensus at the specification level about the coded values that are the best to be used, but there is recognition that some implementation contexts are unable to use the recommended codes for a variety of reasons. Applications should consider adopting the preferred value set where ever possible, as these preferred value sets are the most likely to server interoperability purposes in the future.

When an element is bound to a preferred value set, derived profiles may bind the element to any value set they choose.

1.23.0.2.3.1 Example Bindings

Instances are not expected or even encouraged to draw from the specified value set. The value set merely provides examples of the types of concepts intended to be included.

Example bindings are used when an element has a very broad meaning (such as List.code), or there is no consensus over the correct codes to be used. For these bindings:

  • Coding: the system/code values MAY be one of the codes in the value set.
  • CodeableConcept: one of the coding elements MAY contain a system/code that is in the value set.

Some other coded value MAY be used, or (for a CodeableConcept), a text alternative MAY be provided. Example value sets are provided to assist implementers to understand the correct use of an element. Value sets based on code systems such as SNOMED CT that have restrictive license terms will only be used as example bindings in the base FHIR specification, though implementation guides for particular jurisdictions may adopt value sets that require licenses.

When an element is bound to an example value set, derived profiles may bind the element to any value set they choose.

1.23.0.3 Other notes

  • Subsequent versions of FHIR may replace example value sets with preferred bindings if enough consensus emerges in the space
  • Bindings to value sets provided as part of the specification are always specific to the version of the value set published with the specification. The value set may be sealed by defining a simple list of enumerated codes, or it may include codes by their properties, along with a non-version specific reference to an underlying code system, in which case the list of valid concepts may change over time.