This document provides an agenda and overview for an HL7 FHIR training course. The morning session will include introductions to FHIR, resources, and the RESTful model. Exercises are planned to apply the concepts. The agenda also includes an introduction to the FHIR data model and more exercises before breaking for lunch. The trainer is identified as Ewout Kramer from Furore in Amsterdam, and he has experience with FHIR and healthcare software development.
TheyprobablycraftsomethingthemselvesWe want HL7 to have ananswerto these.If we don’t => someoneelsewill do itand we willlosecredibility.Youcould do itusingv3, but notsolelybased on the downloadable UV-version. Andprobablynot on some country-specificImplementation Guide either (different focus, priorities)
We don’t actually have a formal manifesto, but these are the principles we adhere to.
Who’s read the v3 spec? – modeler & balloter focusedSpec is driven by people who write codeNumerous pieces have been changed because of experience with what worked when trying to implementEven have a test workbench for RESTful servers
9:45
Readilyuseable, contain “the 80%” (What’s the 80%...what’s maximum reuse? That’s HL7’s core business!)Independent of context, fixeddefined behaviour and meaningCanreferenceeachotherUnits of exchange – suggests units of storage forimplementersAddressed through HTTP or other methods
Going from Generic to Specific to ensure compatibility & reuse is a great ideaThe “lower” on this slide you stop to “standardize”, the more flexible is your standard to be used in different context, but…Usually, the more specific standards based on it will diverge and not be cross-compatible (e.g. medication in CDA, CCD, message based national standards)FHIR is pretty specific, so divergence will “only” start from that specific level. Hopefullgivinging better “base” interoperabilityPeople do like re-useable blocks, standards where a prescription remains the same, whether they’re used in messages, documents, etc. CCD/C-CDA is probably popular because it tries to define such blocks across multiple uses, thus going further than the more abstract RIM classes or C-METS.
Youcanconstrainaway stuff youdon’tneedYoucanadd stuff to the basic modelsforyourusecase“Removeandaddbricks as necessary”
Document every resource,everyattributeProvideexamplesDefinehowtouse in REST, Document and MessageManageableby a project lead in a weekend, or you’llbeignored (in favor of localsolutions)
We try very hard to *not* invent stuff that exists elsewhere unless it’s really broken or totally unaligned with the FHIR principles.
Unit of storage / transaction: you cannot send “partial” updates
And few systems will ever see more than 40-50
Even when you think your target will understand all the encoded data, reality is data often gets shared beyond the originally intended contextAllow for exceptions for things like automated device readings, etc.
Always the same structure: intro, UML diagram, “pseudo xml”, bindings, notes, search parametersFormal definitions, mappingsExamples!
No context conduction: if a Condition resource references a particular Patient as it's subject, and it links to a Procedure resource as it's cause, there is no automatic rule or implication that the procedure has the same patient as it's subject.
Referencesbetween resources are notby “business key”, it is *not* the patientid, it’s a REST URI!
Very important concept, comparable with the “Aggregate” notion of Domain Driven Design, for which many useful implementation strategies have been documented on the internet.
Resource Id’s (=URLs) are infrastructural id’s, they differ from “business” identifier.Many Resources also have business identifiers, they are explicitly modeled, like Patient.identifier (even more than one identifier possible!)Business identifiers are completely separate from technical resource id’s
This is not only the URL you use to retrieve the resource, it’s also its id.All URL’s in FHIR are case-sensitive (and so is the id)It is *metadata*, you won’t find this in the Resource’s definition
* Content is the same
Richardson’s REST Maturity Model. We’re at 2.5. Fielding says: “You are not REST”, so we are “RESTful”
You can retrieve any patient using a GET on the patient’s id, which is just an url on the server: /fhir/patient/<id>We have our own MIME-type: “text/xml+fhir”Note that FHIR always uses UTF-8. Since this is not the default for HTTP, the server explicitly mentions thisBut should mean the xml encoding mentions “utf-8” and that the payload is really encoded in utf-8There can be a Byte Order Mark, but hopefully your framework handles all that ;-)The response returns a Content-Location header with a version-specific location….see next slide
This is not only the URL you use to retrieve the resource, it’s also its id.Slide repeated from Resources, with addition of version specific information.All URL’s in FHIR are case-sensitive (and so is the id)
You can retrieve any patient using a GET on the patient’s id, which is just an url on the server: /fhir/Patient/<id>We have our own MIME-type: “application/xml+fhir” and “application/json+fhir”
All but tags have been seen in previous slides
Just a quick look at tags, so the term had been mentionedThis topic needs to be worked out for the 2 day course
Only the Resources are user-definable, other types are “built-in”Derived primitives are patterns -> validation consists of regexp matchingConstrained types are defined using invariants (OCL, Xpath, prose) -> validation using schematron, codeNarrative and Extension are both ONLY used in ResourcesResources can use both (derived) primitives and composite datatypes in its definitionsInfrastructural types need special handling, not general-purpose types
No floats or doubles – either integer or a full decimal value!Difference between instant and (partial) date/timesAttention to timezones
TODO: Search on timestamps (lower, upper bound), converting to zulu, user-timezone, sorting of times etc.* Old-school types built on classis logic and math from the Greek, we have new stuff too…types based on urls!
The content of a primitive is not rendered in XML as a text node but as an attributeNotice how the “system” of a code is now a uri, so unlike in v3 an OID is now ALSO a uri (urn:oid:1.2.3.4.5)
Examples is from http://www.hl7.org/implement/standards/fhir/observation.htmBindings can be Incomplete (HL7 defines some codes for it, but you can add your own), Fixed (HL7 defines the only codes that are allowed) and Example (no specific codes defined, but some are given to give you an idea of what goes in the element)
Examples is from http://www.hl7.org/implement/standards/fhir/observation.htmBindings can be Incomplete (HL7 defines some codes for it, but you can add your own), Fixed (HL7 defines the only codes that are allowed) and Example (no specific codes defined, but some are given to give you an idea of what goes in the element)
Bindings use ValueSets to define what codes are allowed.Patient.administrativeGender has a binding using the valueset “http://hl7.org/fhir/vs/administrative-gender”This valueset includes codes from two code systems http://hl7.org/fhir/v3/AdministrativeGender and http://hl7.org/fhir/v3/NullFlavorSo yes, FHIR reused code systems from v3 (and v2), and has some defined specifically for FHIR.
The element “identifier” is of type HumanId, which in its turn has an element “identifier” of type “Identifier”.The element “telecom” repeats, there is no notion of a “list” in Xml.This nested structure has some consequences for when you are mapping to a “flat” table/row structure….Empty elements are left out
* value[x] means: An element with a name that starts with “value”. The [x] is replaced by the (capitalized) name of the actual datatype
There are references that can reference more than one type of resource! In this example: Resource(Patient | Group | Device)The reference has a “type” element to indicate the kind of Resource that is referencedReferences may be: Relative (on the same server), absolute URL (somewhere external) and internal (not treated here)
Only the Resources are user-definable, other types are “built-in”Derived primitives are patterns -> validation consists of regexp matchingConstrained types are defined using invariants (OCL, Xpath, prose) -> validation using schematron, codeNarrative and Extension are both ONLY used in ResourcesResources can use both (derived) primitives and composite datatypes in its definitionsInfrastructural types need special handling, not general-purpose types
Reallyany FHIR element (Resource, Datatype, Primitive) canbeextended. Just nest an <extension> element under the thingyou want toextendYou should be able to go to the formal definition endpoint and get the definition of the extension.Note: birth order is already provided for in FHIR through the multipleBirthInteger
Only the Resources are user-definable, other types are “built-in”Derived primitives are patterns -> validation consists of regexp matchingConstrained types are defined using invariants (OCL, Xpath, prose) -> validation using schematron, codeNarrative and Extension are both ONLY used in ResourcesResources can use both (derived) primitives and composite datatypes in its definitionsInfrastructural types need special handling, not general-purpose types
“Every resource SHALL include a human readable narrative”Narrative status values: generated, extensions, additional, (and empty)Generated: The contents of the narrative are entirely generated from the structured data in the resource.Extensions: The contents of the narrative are entirely generated from the structured data in the resource and some of the content is generated from extensions.Additional:The contents of the narrative contain additional information not found in the structured data.Empty: the contents of the narrative are some equivalent of "No human-readable text provided for this resource".