HL7 FHIR JSON decoding in BizTalk

| August 25, 2016 | 3

HL7 FHIR represents the next generation healthcare interoperability standard and tries to combine the good stuff from older standards yet leveraging (somewhat) modern things like JSON, XML, HTTP and REST.

With BizTalk you can use the XML-schemas found on the main [FHIR site. As BizTalk is all about XML it’s a perfect match.

A side note is that FHIR does not use any versioning in its namespace which will lead to problems if you need more than one version deployed. As usual this can be solved by modifying the namespace in and out of BizTalk using a namespace altering pipeline component.

FHIR JSON

While FHIR resources can be represented in XML they also can come dressed in JSON. Lets have a look at how we can handle that in BizTalk.

If we try to use the out-of-the-box pipeline components in BizTalk 2013 R2 for JSON –> XML conversion (or any other non-FHIR aware json decoder) the generated XML will not conform with the the FHIR-schemas and specification. The differences are highlighted here http://hl7.org/fhir/json.html#xml but two key ones are:

  • How FHIR resource type are defined.
    • In XML its the actual root-node name
    • In JSON its the ‘resourceType’ field.
  • Values are normally placed in a xml attribute instead of in the elements.

Lets look at a simplified example with a FHIR “Encounter” in JSON and HTTP POST it to a BizTalk (WCF-WebHttp) ReceiveLocation using a pipeline with the new and out-of-the-box BizTalk 2013R2 JSON Decoder.

The source json document used
The source json document used

After the pipeline the XML looks like this:

Several problems. The ResourceType element should not exist and the values should be placed inside value xml attributes.
Several problems. The ResourceType element should not exist and the values should be placed inside value xml attributes.

This does NOT match the FHIR schema.

Solution

To solve this we need a “FHIR aware” JSON to XML Decoder. Luckily there is a great open source one for .NET called .NET API for HL7 FHIR. It´s a really feature rich API that can do a lot more than just FHIR JSON and XML conversion!

Lets create a BizTalk pipeline component using .NET API for HL7 FHIR.

using Hl7.Fhir.Serialization;
using Microsoft.BizTalk.Component.Interop;
using Microsoft.BizTalk.Message.Interop;
using System.IO;

namespace Kramerica.Bts.Fhir.Common.PipelineComponents
{
    public partial class FhirJsonDecoder : IComponent, IBaseComponent, IPersistPropertyBag, IComponentUI
    {
        //Execute is the main method invoked every time a message passes the pipeline component
        public IBaseMessage Execute(IPipelineContext pc, IBaseMessage inmsg)
        {
            IBaseMessagePart bodyPart = inmsg.BodyPart;
            if (bodyPart != null)
            {
                string json;

                using (Stream originalDataStream = bodyPart.GetOriginalDataStream())
                {
                    if (originalDataStream != null)
                    {
                        //Read the json message
                        using (TextReader tr = new StreamReader(originalDataStream))
                        {
                            json = tr.ReadToEnd();
                        }

                        //Use FHIR-NET-API to create a FHIR resource from the json
                        //This 'breaks' the stream a puts the complete message into memory
                        ResourceReader resourceReader = new Hl7.Fhir.Serialization.ResourceReader(FhirParser.FhirReaderFromJson(json));

                        //Use FHIR-NET-API to serialize the resource to XML
                        byte[] resourceXmlBytes = Hl7.Fhir.Serialization.FhirSerializer.SerializeToXmlBytes(resourceReader.Deserialize());

                        //Create the new BizTalk message
                        var memoryStream = new MemoryStream();
                        memoryStream.Write(resourceXmlBytes, 0, resourceXmlBytes.Length);
                        memoryStream.Position = 0;
                        inmsg.BodyPart.Data = memoryStream;
                    }
                }
            }

            return inmsg;
        }
    }
}

As there is a 1:1 correlation between the FHIR ResourceType and xml root node name there is no need to have a configuration parameter for root node name/namespace as we have in the standard JSON decode component. Surely we could have some parameters controlling some aspects of the .NET API for HL7 FHIR but not for this simple proof-of-concept.

Lets see how the XML now looks after a HTTP POST of the source FHIR JSON to the same ReceiveLocation with a pipeline using our new pipeline component.

This looks much better and matches the FHIR XML schemas.
This looks much better and matches the FHIR XML schemas.

Great, we now have a correct FHIR XML instance and we can use it in a BizTalk integration process.

To return/send an instance of a FHIR message we just need to reverse the process by creating a FHIR JSON to FHIR XML BizTalk pipeline component and use that in a send pipeline.

comments powered by Disqus