Skip to content

Instantly share code, notes, and snippets.

View ewoutkramer's full-sized avatar

Ewout Kramer ewoutkramer

View GitHub Profile

A not so short overview of StructureDefinition

While I was working on the new code generator for the .NET API 2.0, I had to review the class hierarchy of FHIR and how we represent this in the StructureDefinitions that are part of the specification. Certainly, if you are working with multiple versions of FHIR and do any kind of metadata work, you will have found yourself trying to remember the answer to questions like: "Is DataRequirements.codeFilter based on Element or BackboneElement?", "Was SimpleQuantity a datatype or a profile on Quantity in R3?" "How did we specify the datatype of Narrative.text in R4? Did that change across FHIR versions?"

Yet again, I found myself digging through tons of StructureDefinitions to find out the details I needed to get the code generation done. I told myself that this time around, I would actually document it, so you (and a future me) would have just a single page to go to.

Resources

Let's first take a look at the Resources. The Resource inheritance

What's new and changed in the FHIR .NET API 2.0?

Over six years ago, we released the first version of the FHIR .NET API. It has grown to a sturdy 1.300 classes and over 300.000 lines of code (admittedly, partly generated) in that time. Even while growing, we have decently managed to keep our library compile-time compatible, making sure that a new version would always compile against your existing code. Of course, we have encountered a number of bigger, breaking changes during that period. Version 2.0 of the API is introducing a first set of some of the most-wanted issues from that list. Over the past months we have worked hard to get them ready, in a way that will hopefully introduce the benefits, without too many breaking changes.

So, what is new? The next sections will give you an overview of the biggest changes, more details can be found in https://github.com/FirelyTeam/fhir-net-api/wiki/Breaking-changes-in-2.0

A new FhirClient

The FhirClient is one of the most-used (and oldest) parts of the li

@ewoutkramer
ewoutkramer / TypeSystemRedesign.md
Last active May 6, 2020 16:28
Document the new ModelInfo and the use of types in ITypedElement - To facilitate discussions about the design (it has not been built yet).

FHIR type information in .NET API 2.0

One of the major areas of work for the 2.0 version of the .NET API was better for working with multiple versions of FHIR within a single application. Since 1.6, we have been splitting up the API in parts that are specific for a given FHIR version, and parts that can be reused across FHIR versions. Additionally, we have seen use of the FHIR type infrastructure to define non-FHIR models like CDA. For this to work smoothly and consistently, we had to refactor the API into parts that are reusable for non-FHIR models, parts that are specific to FHIR and parts that are specific to a certain version of FHIR.

Unfortunately, some of this redesign required a breaking change in the API surface, even for parts that are commonly used. This document details those changes.

The source of truth: ModelInfo

In the 1.x version of the API, ModelInfo exposes a wide variety of utility methods:

  • Mapping between .NET types and Fhir types
DSTU2+STU3
• CachedResolver can now be asked to clear its contents. As well, when doing a cache lookup, you can now optionally specify whether the cache should only be consulted, updated with a new copy or just return the cached entry (last one being the original behaviour)
• Improvements to the serializer to better support _summary serialization of Bundles
• [Excluded for now] Re-instated support for .NET framework 4. Thanks lstratman!
DSTU2+STU3:
• Changed the IElementNavigator interface to enable skipping directly to a child with a given name, thus increasing navigation performance
• Improved performance of validation and fhirpath for POCOs
• Split off IFhirClient interface from the FhirClient implementation (primarily for testing/mocking)
• Many smaller bugfixes
• Improved error messages produced by the validator based on input from the NHS UK
• The validator will now let you put a constraint on children of Resource.contained, Bundle.entry.resource and similar nested resources.
• SerializationUtil.XmlReaderFromString() will no longer try to seek the stream passed in and rewind it.
• TransactionBuilder now has a (default) argument to specify the type of Bundle to build. Thanks mbaltus!
• DirectorySource now has Include/Exclude patterns (with globs) to have more control over directory scans for resource files.

Abstract base core type

    <id value="Element" />
    <url value="http://hl7.org/fhir/StructureDefinition/Element" />
    <name value="Element" />
    <kind value="complex-type" />
    <abstract value="true" />
    <type value="Element" />
@ewoutkramer
ewoutkramer / fhirpath-reflection-classes.puml
Last active March 29, 2017 09:17
UML class diagram for FHIRPath reflection data
@startuml
title FHIRPath Reflection classes
abstract class TypeInfo {
}
class SimpleTypeInfo{
+string name
}
@ewoutkramer
ewoutkramer / snapshot-comparison-stu3.md
Created March 1, 2017 15:15
Overview of differences found in the snapshot generators for the Java and .NET FHIR stack

Comparison of .NET versus Java generated core snapshots

Include the <representation> on primitives

Whenever we encounter a primitive element (like value in all datatypes, and id in all stuctures), the Java generator will emit a <representation> element:

<element id="Account.coverage.id">
      <path value="Account.coverage.id"/>
      <representation value="xmlAttr"/>
@ewoutkramer
ewoutkramer / conformance-domain.md
Last active July 12, 2016 12:06
Draft of text for conformance domain page

Scope

The base FHIR specification describes a set of base resources, frameworks and APIs that are used in many different contexts in healthcare. However there is wide variability between jurisdictions and across the healthcare ecosystem around practices, requirements, regulations, education and what actions are feasible and/or beneficial.

For this reason, the FHIR specification is a "platform specification" - it creates a common platform or foundation on which a variety of different solutions are implemented. As a consequence, this specification usually requires further adaptation to particular contexts of use.

Typically, these adaptations specify:

First try, a ValueSet that follows the human readable page as closely as possible. A parser should look for table headers and fixed phrases to distill a ValueSet resource from this text

ValueSet ParticipantType

ValueSet url: http://hl7.org/fhir/vs/participant-type

A set of codes that can be used to indicate how an individual participates in an encounter.

This valueset defines its own terms in the system http://hl7.org/fhir/participant-type