DSTU2

This page is part of the FHIR Specification (v1.0.2: DSTU 2). The current version which supercedes this version is 4.3.0. For a full list of available versions, see the Directory of published versions

1.18.3 Resource Description Framework (RDF) Representation

FHIR Infrastructure Work GroupMaturity Level: 0Ballot Status: Draft

This page and the RDF forms are particularly prone to change. The page is not part of the current ballot, and so at the most it can be a draft page in DSTU 2. Comments on this and the page content are welcome.

FHIR resources can be represented as an RDF graph serialised in one of a number of RDF syntaxes. When represented in RDF, the resources are described as instances of classes that are also defined in RDF, and published with this specification. This page describes:

Note: this page uses turtle for clarify and readability, but there is no requirement or expectation that turtle should be used in preference to other syntaxes. Note that production turtle instances would not be laid out so clearly either.

Implementer Note: The FHIR RDF format is defined to assist the process of bridging between operational data exchange and formal knowledge processing systems. While the RDF form offers a fully functional representation of FHIR resources, it has very different operational characteristics from the JSON and XML, and would be implemented for different reasons. Systems focused on operational exchange of data would not generally use RDF.

1.18.3.1 RDF Representation of FHIR

The FHIR RDF definitions are defined for the following purposes:

  • Providing the class definitions to support RDF based representation of resource instances
  • Supporting knowledge based analysis of the FHIR specification itself
  • Providing knowledge of use at run-time for converting between FHIR and other content models
  • Supporting reasoning across the information/terminology model boundary

The RDF definitions are published as a series of turtle files RIM and FHIR.

1.18.3.1.1 RDF Class Definitions

The backbone of the RDF definitions are a formal definition of the FHIR resources as RDF classes. Each data type, resource, or element within a resource is defined as rdf:Class with a series of rdf:Property items. Each property has a rdfs:range the specifies the value domain for the property. In most cases, the conversion from the base resource definitions is straightforward.

Constraints are represented in two ways - as OWL statements, and as SHACL predicates. Implementers wishing to enforce constraints can use tools from either language, or process the knowledge represented in these constraints in any other way they see fit.

1.18.3.1.2 Enumerated Codes

FHIR elements that have a code data type with a Required binding to an extensional ValueSet are bound directly to the concepts defined in the code system. The RDF defines the value set, an associated code system, and an RDF class for the code system. Each code in the code system is defined as a singleton class where the class elucidates the definition and relationships of the concept, and the single instance is used to refer to the concept.

1.18.3.1.3 The Ontological RIM

THe RDF definitions for the resources and classes are also mapped to an ontological representation of the v3 RIM, which is also distributed as part of this specification (turtle and RDF/XML). The resources and type definitions refer to both classes and code systems defined as part of the RIM. The references to the classes defined in the RIM are generally only of interest from a RIM perspective; they do not define semantics that are necessary to understand the FHIR resources directly.

The Ontological RIM is a variant of the v3 RIM optimised for its use as an ontology supporting FHIR and other reasonsing uses. It has the following variations from the classical HL7 v3 RIM:

  • II.root and CD.codeSystem are changed to xs:anyUri so that they can accomodate RDF concepts as well as pure OIDs and UUIDs
  • The structure of the CD data type has been re-organised to support validation logic more effectively
  • Only the base structural classes are included (yet?)
  • More: mixins? associations? nullFlavor on associations?

1.18.3.1.4 Other Mappings

In addition to mappings to the Ontological RIM, the RDF contains mappings to other sources of knowledge, including LOINC, SNOMED CT, OBO, etc. In these cases, the mappings reference concepts that are not defined within the RDF content provided as part of this specification, and implementers will need to locate them elsewhere.

1.18.3.2 Decimal Precision

todo.

1.18.3.3 RDF Representation of Profiles

todo.

1.18.3.4 RDF Resource Instances

A FHIR resource is represented by a series of RDF triples, starting with the fixed identifier ":resource". For readability, this page presents instances using turtle, but production instances can use any valid RDF syntax.

@prefix fhir: <http://hl7.org/fhir/> .
@prefix flag: <http://hl7.org/fhir/Flag.> .

:resource a fhir:Flag;...

The ":resource" object has a type predicate ("a") that indicates what kind of resource it is. In addition, the object will have a series of predicates for the properties defined in the RDF class definitions:

:resource a fhir:Flag;
  flag:id "example";
  flag:text [...];
  flag:category [...];
  flag:status fhir:flag-status\#active.

Enumerated fields are represented using an anonymous concept that has an rdf:type which is the concept as defined in the RDF code system definitions.

Property names are defined by class, and follow into the data types:

  flag:category [
    fhir:CodeableConcept.coding [
	  fhir:Coding.system <http://example.org/local>;
	  fhir:Coding.code "admin";
	  fhir:Coding.display "Admin";
	];
	fhir:CodeableConcept.text "admin"
  ];

The primitive types are represented using the same W3C schema based types as in the XML and JSON formats. Since the types are defined in advance, there is not usually a need to specify the type explicitly unless the RDF syntax requires this (e.g. in turtle, it would not be specified).

There are several special issues for the RDF based representation:

1.18.3.4.1 Missing elements

There are a number of elements in the FHIR resources and data types that have an explicit meaning or a default value when they are missing. Default values are represented explicitly in the RDF representation; they are not not omitted. For example, Patient.active has a default value of "false", and is defined like this:

fhir:Patient.active a rdf:Property;
  os:occurs os:Zero-or-one;
  rdfs:range fhir:boolean;
  fhir:default [
     a fhir:boolean;
     fhir:value [ fhir:Boolean.value "true"]
  ].

Since it has a default value, it can never be omitted from an instance:

:resource a fhir:Patient;
  fhir:Patient.active [ fhir:Boolean.value "true"],
  ...etc

Some elements do not have a default value, but they do have a meaning when there is no element present. As an example, if Patient.animal is not present, the patient is a human. In RDF (OWL particularly), reasoners cannot infer meaning from missing elements, so the element must always be present, but may have a value of http://hl7.org/fhir/nil (in RDF, fhir:nil).

Here's a patient resource with an animal property:

:resource a fhir:Patient;
  pat:animal [ ... ]

If the patient is human then the representation will be:

:resource a fhir:Patient;
  pat:animal fhir:nil;

Note: fhir:nil may be used for any property that has no value in a JSON or XML instance, but when the element has a 'meaning when missing', there SHALL be either an explicit value or else fhir:nil in the instance.

1.18.3.4.2 Order

FHIR elements with cardinality > 1 are inherently ordered (though the meaning of the order may not be known, or the order may have no real significance). This order must be maintained when round-tripping FHIR instances.

TODO: it is not yet resolved how this will be done.

1.18.3.4.3 Contained Resources

Contained resources are represented like this:

:resource a fhir:Observation;
  fhir:contained :resource\#23;
  fhir:Observation.subject [
     fhir:Reference.reference [ fhir:string.value :resource\#23]
  ].

:resource\#23 a fhir:Patient;
  fhir:Patient.name [
    fhir:text [ fhir:string.value "John Smith"]
  ].

In order to make it easy to serialise multiple resources, the id within the resource is scoped by the URL of the resource that contains it.

1.18.3.4.4 Extensions

In RDF, extensions are represented in two parts. The first part is a definition of the resource, and the second part is the extension value. Extensions are split like this in RDF to take advantage of RDF and to make reasoning easier.

The first part is the definition. This conveys whether the extension is a modifier, and what type it has:

@prefix ex: <http://hl7.org/fhir/StructureDefinition/> .

ex:birthplace a fhir:ExtensionDefinition;
   rdfs:range fhir:Address;
   fhir:flag fhir:isModifier.

This definition SHALL be present in any instance of an RDF graph where an extension is used. If the extension is a modifier, it SHALL be labelled as such. Additional information from the extension definition MAY be provided, but this is not required, and often is not possible (the minimum mandatory content is also represented in XML and JSON).

The value of an extension is represented as a predicate:

:resource a fhir:Patient;
  ex:birthPlace [ .. properties of address ... ];

The value of the property is the value of the extension, or a complex object with further extensions.

1.18.3.4.5 Concept References

The data type Coding and its container CodeableConcept represent references from a resource to a separate knowledge container. The definitions of the Coding data type are constained by operational considerations around incomplete knowledge, longitudinal version issues, use across multiple contexts, etc., so a mapping process is required to match the information that constitutes the Coding reference to the target RDF concept on which reasoning will be based.

For instance, a reference to a LOINC code in a JSON resource instance takes this form:

{
  "resourceType" : "Observation",
  "code" : {
    "coding" : {
      "system" :  [ fhir:uri.value "http://loinc.org"],
      "code" : [ fhir:code.value "54411-4"],
      "display" : [ fhir:string.value "Rh immune globulin given Qualitative"]
   	},
    "text" : "Rh immune globulin"
  }
}

As an example, in the local LOINC RDF representation, the URI for that LOINC code is http://loinc.org/owl/54411-4. (Note that for many terminologies, including LOINC, there is no standard RDF representation and multiple forms with different addressing schemes are available. Where standard representations exist, implementers SHOULD use the same addressing scheme.)

There is no algorithmic conversion between the system/code and the equivalent RDF concept; instead, a mapping table or process of some kind must be maintained. These mapping tables have variable complexity. In the worst case - codes that have the form of an expression - considerable syntactic and semantic logic is required to perform the mapping. For this reason, the reconciliation process is often performed as a preprocessing step prior to using the RDF for reasoning. Once the reconciliation process is complete, the resolved concepts are stated as rdf:type assertions on the concept:

@prefix loinc: <http://loinc.org/owl#> .

:resource a fhir:Observation;
  fhir:Observation.code [
    a loinc:54411-4;
    fhir:CodeableConcept.coding [
      fhir:Coding.system [ fhir:uri.value <http://loinc.org>] ;
      fhir:Coding.code [ fhir:code.value "54411-4" ];
      fhir:Coding.display [ fhir:string.value "Rh immune globulin given Qualitative"];
      ];
    fhir:CodeableConcept.text [ fhir:string.value "Rh immune globulin" ];
  ].

Typically, these type assertions are only used in the RDF form, but they can be carried as a normal FHIR extension in both the XML and JSON forms:

{
  "resourceType" : "Observation",
  "code" : {
    "extension" : {
      "url" : "http://hl7.org/fhir/StructureDefinition/rdftype",
      "valueUri" : "http://loinc.org/owl/54411-4"
    },
    "coding" : {
      "system" : "http://loinc.org",
      "code" : "54411-4",
      "display" : "Rh immune globulin given Qualitative"
   	},
    "text" : "Rh immune globulin"
  }
}

Implementers should note that these type assertions often reference local ontologies, and the correct URI may be scope dependent or may vary on a different lifecycle due to the coding information itself, and so it is usually not appropriate to persist these references.

These type assertions may be made against either CodeableConcept or Coding data types; when the FHIR resource property has a type of CodeableConcept they should be made at this level rather than on the Coding.

1.18.3.4.6 Resource References

The Reference data type represents a reference from one resource to another. The reference may be a relative URL, and resolution is subject to local rules and context (e.g. server API [base], or context in a bundle). For the same reasons as with Concept References, this can be reconciled with the actual concrete resource instance in the RDF. As an example, a reference to a resource would be represented like this in JSON:

{
  "resourceType" : "Observation",
  "subject" : {
    "reference" : "Patient/example"
  }
}

In RDF, this is represented as an anonymous instance of the data type reference:

:resource a fhir:Observation;
  fhir:Observation.subject [
    fhir:Reference.reference [ fhir:string.value "Patient/example" ];
  	a pat:example
  ].

If this has been resolved to a specific instance, then the subject is directly assigned to the instance:

:resource a fhir:Observation;
  fhir:Observation.subject :patient-example.
  
:patient-example fhir:Reference.reference [ fhir:string.value "Patient/example" ];

The details of the reference are added to the target resource. TODO: this means that traceability of the reference is lost, and it's not round-trippable if the reconciliation includes resources that have more than one literal value to reference in the target resource

@prefix pat: <http://acme.com/services/fhir/Patient/#> 

:resource a fhir:Observation;
  fhir:Observation.subject [
    fhir:Reference.reference [ fhir:string.value "Patient/example" ];
  	a pat:example
  ].

1.18.3.4.7 Other Stuff

Todo: implement a template for RDF? (turtle? RDF XML - yuck) Todo: note that there's no canonical form for RDF, nor any defined support for signatures.

1.18.3.5 Using RDF with the REST API

When using RDF on the REST API, the following media types apply:

  • text/turtle - RDF as Turtle
  • application/rdf+xml - RDF in XML format
  • text/n3 - N3 format

Implementations are encouraged to support this list. However servers are not required to support all these, and may support additional syntaxes.