firely-net-sdk icon indicating copy to clipboard operation
firely-net-sdk copied to clipboard

How to quickly support versions other than STU3 R4 R5 (such as version 1.6.0 1.8.0 3.3.0 or customized versions) ?

Open yankunhuang-pku opened this issue 3 years ago • 3 comments

We now have a C # based tool that supports FHIR operations by using ITypedElement.

If we want to support multiple versions, we will rely on your library in each version. For example, if our tool wants to support R4, it needs to rely on HL7.fhir.R4, but in this case, we cannot support other sub versions or user-defined versions (versions that do not conform to FHIR).

Can we convert the input data to ITypedElement by providing some specification files (instead of new an object PocoStructureDefinitionSummaryProvider new PocoStructureDefinitionSummaryProvider())?

yankunhuang-pku avatar Jan 18 '22 10:01 yankunhuang-pku

Hi @yankunhuang-pku , thanks for your feedback on our SDK.

What do you mean by versions? The FHIR versions, like STU3, R4, R4B and R5 (see also here)?

If the answer is yes, then you can work with aliases in your project. For example place the following snippet in your project file:

  <ItemGroup>
    <PackageReference Include="Hl7.Fhir.Specification.STU3" Version="3.8.0" GeneratePathProperty="true" ExcludeAssets="contentFiles" />
   <PackageReference Include="Hl7.Fhir.Specification.R4" Version="3.8.0" GeneratePathProperty="true" ExcludeAssets="contentFiles" />
  </ItemGroup>

  <Target Name="AddPackageAliases" BeforeTargets="ResolveReferences" Outputs="%(PackageReference.Identity)">
    <ItemGroup>
      <ReferencePath Condition="'%(FileName)'=='Hl7.Fhir.STU3.Core'">
        <Aliases>stu3</Aliases>
      </ReferencePath>
      <ReferencePath Condition="'%(FileName)'=='Hl7.Fhir.R4.Core'">
        <Aliases>r4</Aliases>
      </ReferencePath>
    </ItemGroup>
  </Target>

Then you can do this:

extern alias r4;
extern alias stu3;
using System;
using Hl7.Fhir.ElementModel;
using Hl7.Fhir.Serialization;

namespace Firely.Example
{
    internal class Foo
    {
        public ITypedElement Parse(string json, string fhirVersion) =>
            fhirVersion switch
            {
                "STU3" => FhirJsonNode.Parse(json).ToTypedElement(new stu3::Hl7.Fhir.Specification.PocoStructureDefinitionSummaryProvider()),
                "R4" => FhirJsonNode.Parse(json).ToTypedElement(new r4::Hl7.Fhir.Specification.PocoStructureDefinitionSummaryProvider()),
                _ => throw new ArgumentException("Unsupported or unknown FHIR version"),
            };
    }
}

Perhaps this solves your problem. In any case you should have an implementation of IStructureDefinitionSummaryProvider, because that provides the type information.

marcovisserFurore avatar Jan 18 '22 14:01 marcovisserFurore

Yes, your understanding is correct. However, we only have STU3, R4, R4B and R5 libraries. What should we do if we want to support other sub-versions such as 4.5.0 in this link you provided because you don't provide a library called Hl7.Fhir.Specification.R4.5.0?

In other words, is there a way to directly convert input json to ITypedElement using the downloaded specification file, such as this compressed package (http://hl7.org/fhir/2020Sep/fhir-spec.zip)?

yankunhuang-pku avatar Jan 19 '22 02:01 yankunhuang-pku

Indeed, we do not provide libraries for subversions such as 4.5.0. That would be a burden on our maintenance. With 4 major versions it is already a day job to maintain all the different versions.

If you want to support a sub-version you can change the version of our library. For example:

  • 3.8.0-R4B supports FHIR Release 4.3.0-snapshot1
  • 3.8.0-R5 supports FHIR Release 5.0.0-snapshot1
  • 3.3.0-R5 support FHIR Release 4.6.0

The Poco classes (the equivalent of FHIR Resources) are generated and compiled in the libraries Hl7.Fhir.[STU3 | R4 | R4B | R5] and the latest version of those libraries contains the latest corresponding FHIR release.

In theory this could also work:

        public ITypedElement? Parse(string json, string fhirRelease)
        {
             if (fhirRelease == "R4")
             {
                var resolver = new CachedResolver(new ZipSource(@"C:\Data\projects\specification-R5-4.6.0.zip"));

                return FhirJsonNode.Parse(json).ToTypedElement(new StructureDefinitionSummaryProvider(resolver));
            }
            return null;
        }

So the ITypedElement is not built with a PocoStructureDefinitionSummaryProvider but with a StructureDefinitionSummaryProvider. This provider needs a resolver to resolve the resource for their type information. In this case we use the specification.zip, which contains all resources of the particular FHIR resource. This zip files is included in the Hl7.Fhir.Specification.[STU3 | R4 | R4B | R5] nuget packages. When you extract these and rename them like I did in the example, you will be able to convert Json to an ITypedElement. We have never tested this and no guarantees that it will work. With this approach you can no longer use the pocos as they differ for each version in a release as I have already explained.

marcovisserFurore avatar Jan 19 '22 13:01 marcovisserFurore

Answered, closing administratively.

ewoutkramer avatar Apr 12 '23 16:04 ewoutkramer