More than six years ago we released the first version of the Firely .NET SDK (formerly know as 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 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 SDK is introducing a first set of some of the most-wanted improvements from that list. Over the past few months we have worked hard to get them ready in order to introduce their benefits without too many breaking changes.
So, what is new? The next sections will give you an overview of the biggest changes. If you want more details, you can find them here: https://github.com/FirelyTeam/firely-net-sdk/wiki/Breaking-changes-in-2.0
FhirClient is one of the most-used (and oldest) parts of the library, and was still using Microsoft’s HttpWebRequest and HttpWebResponse as the underlying technology. These classes have been replaced quite a while ago, and have been upgraded to use Microsoft’s newer
HttpClient, providing more flexibility to customize and manipulate the HTTP traffic. It also has better support for newer TLS versions. Special thanks to Brad Barnich and Devereux Henley, our community members, who provided most of the code to get this task done.
We have made this a drop-in replacement: when you are using the
FhirClient, you will be using this new implementation in 2.0. The interface has only slightly changed and, if you run into problems, the older client based on
HttpWebRequest is still available (keep in mind that it is now called LegacyFhirClient (marked
[Obsolete])). It is strongly recommended to use the new FhirClient implementation!
When HL7 initially released the DSTU2 version of FHIR, a lot of the data models and functionality had changed. Therefore we decided to ship two separate versions of the Firely .NET SDK, both being more or less identical copies but each supporting only one version.
This process has continued for STU3 and R4. As these recent versions of FHIR have more and more in common, we have started to identify and isolate common parts. A year ago, we split off common code from the
firely-net-sdk repo into the submodule repo called
firely-net-common. In 2.0, thanks to being able to make some minor breaking changes to the SDK and dropping DSTU2 support, we have managed to move some of the most-used common base resources to the common library:
Element are just a few I should mention in this respect. This means that the POCO classes representing FHIR data (like
Patient) now share a common base class across all FHIR versions. This makes it much easier to write applications supporting multiple FHIR versions. We would like to make it even easier but we have taken a major step already.
We also backported the type hierarchy introduced in the early drops of R5 into the STU3 and R4 versions of the SDK. All these versions share the same backbone of abstract base classes.
A large part of the I/O activities of the SDK is caused by validation and the parsers/serializers trying to reach out to the conformance resources (FHIR’s metadata) supplied by the FHIR specification. These are abstracted behind resolvers, which some of you might have created specific implementations for. Until now, these were synchronous. To enable better scalability, we are introducing
IAsyncResourceResolver and all functionality in the SDK using resolvers will accept either sync or async resolvers.
We have had support for FhirPath (http://hl7.org/fhirpath/) for quite a while. But, this was based on the pre-normative versions of the language shipped with FHIR DSTU2. This was slightly adapted in STU3. HL7 has recently published the final “normative” version of FhirPath. This is not only used in FHIR (mostly for formulating business rules in StructureDefinition/profile validation) but also in CQL.
The normative version has an expanded set of math and string manipulation operations, introduces quantities, better handling of date/time precision. The normative version does introduce a few breaking changes and so is not fully compatible with the pre-normative version. However you will find that most of the FhirPath statements you have used in DSTU2/STU3 will still work.
2.0 does not yet support some of the more experimental parts of FhirPath Normative, specifically:
- Quantity comparisons with different units and quantity math
- Date/time math
- The new
We will be adding these features gradually over the next months.
There is a whole host of smaller changes, mostly removal of methods that have been marked as
[Obsolete] for a while. Also, we removed some almost empty namespaces, which were created by accident in the previous versions. Most of the time, just removing the current incorrect
using statement would suffice to make things build again.
With FHIR’s growing popularity, its technologies (like serialization, type system, and conformance resources) were used to support non-FHIR models like CDA. The scope of some of FHIR’s primary DSLs (mainly FhirPath and the mapping language) has been broadened to be used within CQL and even map non-FHIR models to non-FHIR models.
To keep up with this expanded use, we have started to make parts of the SDK more generic. We removed code that assumes that only a pure FHIR context would use it. These changes will take quite a while to materialize. Nonetheless, the most visible step in the 2.0 release is the introduction of a shared set of primitive datatypes called the “system types” which are shared between FHIR, CQL, FhirPath, and the Mapping Language. These types express a shared notion of equality, order, and a shared set of (mathematical) operations that can be performed on them. Most users will not be influenced by these changes as these are mainly internal and they will only become visible in subsequent versions of the SDK in the non-POCO parts of the Firely .NET SDK. These are mainly notable if you use
IStructureDefinitionSummary or the
There is no DSTU2 version of the 2.0 library. We have seen the use of DSTU2 decline sharply over the past year. Additionally there were some significant changes going from DSTU2 to STU3 (and later). We could not have introduced some of the improvements in this version if we kept trying to support DSTU2. Finally, this is a volunteer project and there’s a limit on how much time we can spend supporting older versions.
The new 2.0 release is available on NuGet (look for Hl7.Fhir.Core and Hl7.Fhir.Specification). If you want to compile it yourself, make sure you checkout either the
develop-r4 branch (https://github.com/FirelyTeam/firely-net-sdk/tree/develop-stu3) and the
develop branch of the submodule repository (https://github.com/FirelyTeam/firely-net-common/tree/develop).