Skip directly to search

Skip directly to content

 

EHR to HL7 FHIR Integration: The Software Developer’s Guide – Part 2

 
 

Software Engineering | Matjaz Bravc |
20 July 2021

Welcome to the second post of this blog series where I show you how to create simple custom EHR to HL7 FHIR* integration using the latest Microsoft tech stack. In the first article, I introduced the HL7 FHIR standard and the .NET 5 framework. In this second post, I will share how you can integrate Patients into your solution. In the final part, I will describe how to integrate Patient Observations (blood tests).

HL7 FHIR PATIENTS

FHIR includes many different Resources, one of which is the Patient Resource. Official documentation states that this Resource covers data about patients (and animals) involved in a wide range of health-related activities, including:

  • Curative activities
  • Psychiatric care
  • Social services
  • Pregnancy care
  • Nursing and assisted living
  • Dietary services
  • Tracking of personal health and exercise data

The data in the Resource covers the “who” information about the patient: its attributes are focused on the demographic information necessary to support the administrative, financial, and logistic procedures. A patient record is generally created and maintained by each organisation who provides care for a patient. A patient or animal receiving care at multiple organisations may therefore have their information present in multiple Patient Resources.

Let’s start with the implementation. I assume that you already have some development experience, so I will not go into detail on how to use Visual Studio 2019 and NuGet Packages.

But first – architecture. I created three new projects:

  1. Hl7.Fhir.Common.Contracts – class library
  2. Hl7.Fhir.Common.Core – class library
  3. Hl7.Fhir.OpenAPI – web application

The Hl7.Fhir.Common.Contracts library contains mostly data models and converters which are used across the solution.

The Hl7.Fhir.Common.Core library contains common services, attributes, extensions, etc.

Hl7.Fhir.OpenAPI – this is the start-up web API project which implements OpenAPI specifications with the following features as described by Swagger: The OpenAPI Specification (OAS) defines a standard, programming-language-agnostic interface description for HTTP APIs. This allows both humans and computers to discover and understand the capabilities of a service without requiring access to source code, additional documentation, or the inspection of network traffic. When properly defined via OpenAPI, a consumer can understand and interact with the remote service with a minimal amount of implementation logic. Similar to what interface descriptions have done for lower-level programming, the OpenAPI specification removes guesswork when calling a service.

The final solution looks like this:

Doctor sitting at desk with laptop and tablet

CONFIGURATION

The web API is configured to use the public FHIR server UHN_HAPI Server (R4), which is regularly purged and reloaded with fixed test data. Of course, you can use a different FHIR server from the list of FHIR test servers. For logging, I’ve used Serilog, which is configured with a Serilog configuration section in the appsettings.json file:

Doctor sitting at desk with laptop and tablet

The EHR system communicates with OpenAPI through different controllers/endpoints. For a Patient, there are several endpoints available. Using Swagger UI “allows anyone – be it your development team or your end consumers – to visualize and interact with the API’s resources without having any of the implementation logic in place. It’s automatically generated from your OpenAPI Specification, with the visual documentation making it easy for back end implementation and client side consumption.” Pretty cool, huh!

Doctor sitting at desk with laptop and tablet

CREATE A NEW PATIENT

Let’s go through the typical data flow and create a new Patient. For this purpose, I will use the api/Patient/Create endpoint and send the following PatientDto in a body request. The result is a new Patient being created:

Doctor sitting at desk with laptop and tablet

DIG INTO THE CODE

Now, let’s go into the details. The PatientDto model was transferred to the /api/Patient/Create endpoint. After the model validation, PatientService is called using the CreatePatientAsync method.

Doctor sitting at desk with laptop and tablet

In the first step, the CreatePatientAsync method converts PatientDto data into an FHIR Patient resource, and in the next step, it validates a new Patient resource. If the validation was successful, then FhirClient creates a Patient on the FHIR server and returns it with a new ID.

Doctor sitting at desk with laptop and tablet

MAPPING PATIENTDTO TO THE FHIR PATIENT RESOURCE

A crucial part of our integration is mapping the EHR model to the FHIR resource. In our case, the EHR model is PatientDto (DTO is Data Transfer Object), which has to be converted into the FHIR Patient resource. This is done using a model converter:

Doctor sitting at desk with laptop and tablet Doctor sitting at desk with laptop and tablet

PatientController supports most common endpoints, and you can use it to get a Patient by identifier or by resource ID, you can update an existing Patient, and even import a list of Patients from a CSV file (an example CSV file is included in the Resources/Files folder of this solution).

In the next post, I will present how you can integrate the FHIR Observation resource.
Find example source code for this series on Endava’s GitHub.

PREREQUISITES

Visual Studio 2019 16.8.1 or higher
.NET 5.x

TAGS, TECHNOLOGIES AND SOURCES

Swagger – interactive API documentation
API-Docs – friendly API documentation
Serilog – flexible, structured logger
FluentValidation – a popular .NET library for building strongly-typed validation rules
Firely .NET SDK – the official HL7 FHIR SDK in .NET

ADDITIONAL RESOURCES

Extra documentation for FhirClient
HL7 FHIR Restful API specification
Firely.NET SDK FHIR Community
List of FHIR test servers

* HL7® and FHIR® are the registered trademarks of Health Level Seven International.

Matjaz Bravc

Senior Developer

Matjaz is a Senior Software Engineer with more than 15 years of experience in designing and developing scalable applications in an Agile manner. His experience ranges across various fields and technologies (mostly Microsoft stack), and he is an expert .NET developer with strong backend C# development experience. His expertise also includes mission-critical distributed systems with a strong focus on object-oriented programming, microservice architecture, data warehouse design, and test-driven development. Matjaz likes to spend his free time away from the computer, with hobbies such as scuba diving, canoeing, standup paddling, and mountain biking.

 

Related Articles

  • 16 November 2021

    Create Production-Ready, Automated Deliverables Using a Build Pipeline for Games – Part 1

  • 20 July 2021

    EHR to HL7 FHIR Integration: The Software Developer’s Guide – Part 2

  • 29 June 2021

    EHR to HL7 FHIR Integration: The Software Developer’s Guide – Part 1

  • 02 December 2020

    8 Tips for Sharing Technical Knowledge – Part 2

  • 12 November 2020

    8 Tips for Sharing Technical Knowledge – Part 1

 

From This Author

  • 24 August 2021

    EHR to HL7 FHIR Integration: The Software Developer’s Guide – Part 3

  • 29 June 2021

    EHR to HL7 FHIR Integration: The Software Developer’s Guide – Part 1

Most Popular Articles

11 Things I wish I knew before working with Terraform – part 2
 

Architecture | Julian Alarcon | 23 July 2019

11 Things I wish I knew before working with Terraform – part 2

11 Things I wish I knew before working with Terraform – part 1
 

Architecture | Julian Alarcon | 25 June 2019

11 Things I wish I knew before working with Terraform – part 1

EHR to HL7 FHIR Integration: The Software Developer’s Guide – Part 1
 

Software Engineering | Matjaz Bravc | 29 June 2021

EHR to HL7 FHIR Integration: The Software Developer’s Guide – Part 1

How User Experience Design is Increasing ROI
 

Next Gen Insights | Valentin Andrei Iordache | 23 November 2021

How User Experience Design is Increasing ROI

AWS Serverless with Terraform – Best Practices
 

Architecture | Vlad Cenan | 10 December 2019

AWS Serverless with Terraform – Best Practices

Kubernetes Design Principles Part 1
 

Architecture | Armen Kojekians | 30 April 2019

Kubernetes Design Principles Part 1

Elasticsearch and Apache Lucene: Fundamentals Behind the Relevance Score
 

Insights Through Data | Alveiro Garcia | 08 June 2021

Elasticsearch and Apache Lucene: Fundamentals Behind the Relevance Score

Create Production-Ready, Automated Deliverables Using a Build Pipeline for Games – Part 1
 

Software Engineering | Olaf Spiewok | 16 November 2021

Create Production-Ready, Automated Deliverables Using a Build Pipeline for Games – Part 1

Challenges in creating relevant test data without using personally identifiable information
 

Testing | Alex Gatu | 25 February 2020

Challenges in creating relevant test data without using personally identifiable information

 

Archive

  • 23 November 2021

    How User Experience Design is Increasing ROI

  • 16 November 2021

    Create Production-Ready, Automated Deliverables Using a Build Pipeline for Games – Part 1

  • 19 October 2021

    A Basic Setup for Mass-Testing a Multiplayer Online Board Game

  • 24 August 2021

    EHR to HL7 FHIR Integration: The Software Developer’s Guide – Part 3

  • 20 July 2021

    EHR to HL7 FHIR Integration: The Software Developer’s Guide – Part 2

  • 29 June 2021

    EHR to HL7 FHIR Integration: The Software Developer’s Guide – Part 1

  • 08 June 2021

    Elasticsearch and Apache Lucene: Fundamentals Behind the Relevance Score

  • 27 May 2021

    Endava at NASA’s 2020 Space Apps Challenge

  • 27 January 2021

    Following the Patterns – The Rise of Neo4j and Graph Databases

  • 12 January 2021

    Data is Everything

  • 05 January 2021

    Closing-the-gap-between-the-product-owner-and-the-team-part-3

We are listening

How would you rate your experience with Endava so far?

We would appreciate talking to you about your feedback. Could you share with us your contact details?