Building a FHIR client with HAPI and .NET (1)...Building a FHIR client with HAPI and .NET (1) ......
Transcript of Building a FHIR client with HAPI and .NET (1)...Building a FHIR client with HAPI and .NET (1) ......
![Page 1: Building a FHIR client with HAPI and .NET (1)...Building a FHIR client with HAPI and .NET (1) ... • The standard specifies a RESTful API for interacting with that model • For example,](https://reader034.fdocuments.net/reader034/viewer/2022042221/5ec7e4bde396e9508e2148aa/html5/thumbnails/1.jpg)
HL7®, FHIR® and the flame Design mark are the registered trademarks of Health Level Seven International and are used with permission.
Amsterdam, 14-16 November | @HL7 @FirelyTeam | #fhirdevdays | www.fhirdevdays.com
Building a FHIR client with HAPI and .NET (1)
James Agnew and Mirjam Baltus
![Page 2: Building a FHIR client with HAPI and .NET (1)...Building a FHIR client with HAPI and .NET (1) ... • The standard specifies a RESTful API for interacting with that model • For example,](https://reader034.fdocuments.net/reader034/viewer/2022042221/5ec7e4bde396e9508e2148aa/html5/thumbnails/2.jpg)
Who are we?
• Name: James Agnew• Background:
• Software Developer by day• Project lead for HAPI for 14 years• Lead Architect: Centre for Global
eHealth Innovation• CTO: Smile CDR
• Name: Mirjam Baltus• Background:
• Firely team• FHIR trainer & Support
![Page 3: Building a FHIR client with HAPI and .NET (1)...Building a FHIR client with HAPI and .NET (1) ... • The standard specifies a RESTful API for interacting with that model • For example,](https://reader034.fdocuments.net/reader034/viewer/2022042221/5ec7e4bde396e9508e2148aa/html5/thumbnails/3.jpg)
Prerequisites
• This tutorial assumes you are at least comfortable with the following:• FHIR• Java or C#• An IDE (Eclipse or IntelliJ IDEA recommended for Java, Visual Studio for .Net)• Apache Maven (build system) or NuGet Package manager
![Page 4: Building a FHIR client with HAPI and .NET (1)...Building a FHIR client with HAPI and .NET (1) ... • The standard specifies a RESTful API for interacting with that model • For example,](https://reader034.fdocuments.net/reader034/viewer/2022042221/5ec7e4bde396e9508e2148aa/html5/thumbnails/4.jpg)
FHIR: A Quick Recap (1)
• FHIR offers a model for Healthcare concepts• For example, Patient:
![Page 5: Building a FHIR client with HAPI and .NET (1)...Building a FHIR client with HAPI and .NET (1) ... • The standard specifies a RESTful API for interacting with that model • For example,](https://reader034.fdocuments.net/reader034/viewer/2022042221/5ec7e4bde396e9508e2148aa/html5/thumbnails/5.jpg)
FHIR: A Quick Recap (2)
• The standard specifies a RESTful API for interacting with that model• For example, a search:
![Page 6: Building a FHIR client with HAPI and .NET (1)...Building a FHIR client with HAPI and .NET (1) ... • The standard specifies a RESTful API for interacting with that model • For example,](https://reader034.fdocuments.net/reader034/viewer/2022042221/5ec7e4bde396e9508e2148aa/html5/thumbnails/6.jpg)
FHIR: A Quick Recap (3)
• FHIR has had several releases• FHIR DSTU1 (Released 2014)• FHIR DSTU2 (Released 2015)• FHIR R3 (Released 2017)• FHIR R4 (To be released 2019)
• This presentation focuses on STU3 but the concepts apply to all versions
• For our purposes: DSTU / STU / R are interchangeable
![Page 7: Building a FHIR client with HAPI and .NET (1)...Building a FHIR client with HAPI and .NET (1) ... • The standard specifies a RESTful API for interacting with that model • For example,](https://reader034.fdocuments.net/reader034/viewer/2022042221/5ec7e4bde396e9508e2148aa/html5/thumbnails/7.jpg)
API background
![Page 8: Building a FHIR client with HAPI and .NET (1)...Building a FHIR client with HAPI and .NET (1) ... • The standard specifies a RESTful API for interacting with that model • For example,](https://reader034.fdocuments.net/reader034/viewer/2022042221/5ec7e4bde396e9508e2148aa/html5/thumbnails/8.jpg)
Java
• HAPI started in 2001 as an HL7 v2 Library• Built to support a simple web portal, now used in applications around
the world
HL7 v2 - http://hl7api.sourceforge.netFHIR - http://hapifhir.io
• HAPI is now the Java Reference Implementation
![Page 9: Building a FHIR client with HAPI and .NET (1)...Building a FHIR client with HAPI and .NET (1) ... • The standard specifies a RESTful API for interacting with that model • For example,](https://reader034.fdocuments.net/reader034/viewer/2022042221/5ec7e4bde396e9508e2148aa/html5/thumbnails/9.jpg)
.Net
• Has been developed with the FHIR standard from 2011• Hl7.Fhir.<version>• The official Reference Implementation for .Net
• Source: https://github.com/ewoutkramer/fhir-net-api• Documentation: http://docs.simplifier.net/fhirnetapi/index.html
![Page 10: Building a FHIR client with HAPI and .NET (1)...Building a FHIR client with HAPI and .NET (1) ... • The standard specifies a RESTful API for interacting with that model • For example,](https://reader034.fdocuments.net/reader034/viewer/2022042221/5ec7e4bde396e9508e2148aa/html5/thumbnails/10.jpg)
Code examples
• See the documentation of your API
• Take a look at:https://github.com/firelyteam/fhirstarters
![Page 11: Building a FHIR client with HAPI and .NET (1)...Building a FHIR client with HAPI and .NET (1) ... • The standard specifies a RESTful API for interacting with that model • For example,](https://reader034.fdocuments.net/reader034/viewer/2022042221/5ec7e4bde396e9508e2148aa/html5/thumbnails/11.jpg)
The model
![Page 12: Building a FHIR client with HAPI and .NET (1)...Building a FHIR client with HAPI and .NET (1) ... • The standard specifies a RESTful API for interacting with that model • For example,](https://reader034.fdocuments.net/reader034/viewer/2022042221/5ec7e4bde396e9508e2148aa/html5/thumbnails/12.jpg)
Structures JARs
• HAPI supports multiple versions of FHIR via different “structures JARs”
hapi-fhir-structures-dstu-2.5.jar
hapi-fhir-structures-dstu2-2.5.jar
hapi-fhir-structures-dstu3-2.5.jar
FHIR Version HAPI Version
ca.uhn.fhir.model.dstu.resources.Patient
ca.uhn.fhir.model.dstu2.resources.Patient
org.hl7.fhir.dstu3.model.Patienthapi-fhir-structures-r4-3.0.0.jar
org.hl7.fhir.r4.model.Patient
Patient Resource ModelsPatient Resource ModelsPatient Resource ModelsPatient Resource Models
![Page 13: Building a FHIR client with HAPI and .NET (1)...Building a FHIR client with HAPI and .NET (1) ... • The standard specifies a RESTful API for interacting with that model • For example,](https://reader034.fdocuments.net/reader034/viewer/2022042221/5ec7e4bde396e9508e2148aa/html5/thumbnails/13.jpg)
FHIR versions in .Net
• Different NuGet Packages• Hl7.Fhir.DSTU2• Hl7.Fhir.STU3• Hl7.Fhir.R4
• All have Hl7.Fhir.Model namespace
![Page 14: Building a FHIR client with HAPI and .NET (1)...Building a FHIR client with HAPI and .NET (1) ... • The standard specifies a RESTful API for interacting with that model • For example,](https://reader034.fdocuments.net/reader034/viewer/2022042221/5ec7e4bde396e9508e2148aa/html5/thumbnails/14.jpg)
A FHIR resource
![Page 15: Building a FHIR client with HAPI and .NET (1)...Building a FHIR client with HAPI and .NET (1) ... • The standard specifies a RESTful API for interacting with that model • For example,](https://reader034.fdocuments.net/reader034/viewer/2022042221/5ec7e4bde396e9508e2148aa/html5/thumbnails/15.jpg)
A FHIR Resource class in C#
public partial class Observation : Hl7.Fhir.Model.DomainResource
/// <summary>/// Codes providing the status of an observation./// (url: http://hl7.org/fhir/ValueSet/observation-status)/// </summary>public enum ObservationStatus {Registered, Preliminary, Final, …}
var obs = new Observation();obs.Status = ObservationStatus.Preliminary;
![Page 16: Building a FHIR client with HAPI and .NET (1)...Building a FHIR client with HAPI and .NET (1) ... • The standard specifies a RESTful API for interacting with that model • For example,](https://reader034.fdocuments.net/reader034/viewer/2022042221/5ec7e4bde396e9508e2148aa/html5/thumbnails/16.jpg)
A FHIR Resource class in HAPI
• Resource definition classes implement IBaseResource• Enumerations are available for
required value sets
// Create a resource instanceObservation obs = new Observation();obs.setStatus(ObservationStatus.FINAL);
![Page 17: Building a FHIR client with HAPI and .NET (1)...Building a FHIR client with HAPI and .NET (1) ... • The standard specifies a RESTful API for interacting with that model • For example,](https://reader034.fdocuments.net/reader034/viewer/2022042221/5ec7e4bde396e9508e2148aa/html5/thumbnails/17.jpg)
Datatypes
In Java• Primitive classes are named
[name]Type• Primitive types include:
StringType, BooleanType• Composite types include:
Address, Ratio, HumanName
In C#• Primitive classes are named
FhirType• For datatypes with same name in
C#
• Primitive types include:FhirString, FhirBoolean
• Composite types include:Address, Ratio, HumanName
![Page 18: Building a FHIR client with HAPI and .NET (1)...Building a FHIR client with HAPI and .NET (1) ... • The standard specifies a RESTful API for interacting with that model • For example,](https://reader034.fdocuments.net/reader034/viewer/2022042221/5ec7e4bde396e9508e2148aa/html5/thumbnails/18.jpg)
Datatypes example
public CodeableConcept Code { get; set; }
public List<Identifier> Identifier { get; set; }
![Page 19: Building a FHIR client with HAPI and .NET (1)...Building a FHIR client with HAPI and .NET (1) ... • The standard specifies a RESTful API for interacting with that model • For example,](https://reader034.fdocuments.net/reader034/viewer/2022042221/5ec7e4bde396e9508e2148aa/html5/thumbnails/19.jpg)
Using datatypes
C#// Add an "identifier" elementvar identifier = new Identifier("http://example.org", "123456");obs.Identifier.Add(identifier);
Java// Add an "identifier" elementIdentifier identifier = obs.addIdentifier();identifier.setSystem("http://example.org").setValue("123456");
![Page 20: Building a FHIR client with HAPI and .NET (1)...Building a FHIR client with HAPI and .NET (1) ... • The standard specifies a RESTful API for interacting with that model • For example,](https://reader034.fdocuments.net/reader034/viewer/2022042221/5ec7e4bde396e9508e2148aa/html5/thumbnails/20.jpg)
Primitives are not really primitive…
![Page 21: Building a FHIR client with HAPI and .NET (1)...Building a FHIR client with HAPI and .NET (1) ... • The standard specifies a RESTful API for interacting with that model • For example,](https://reader034.fdocuments.net/reader034/viewer/2022042221/5ec7e4bde396e9508e2148aa/html5/thumbnails/21.jpg)
Why would you use the non-primitive version?
var name = new HumanName();
name.Family = "Baltus-Bakker";
• Adding extensions cannot be done on primitives!
name.FamilyElement.AddExtension("http://hl7.org/fhir/StructureDefinition/humanname-partner-name",new FhirString("Baltus"));
![Page 22: Building a FHIR client with HAPI and .NET (1)...Building a FHIR client with HAPI and .NET (1) ... • The standard specifies a RESTful API for interacting with that model • For example,](https://reader034.fdocuments.net/reader034/viewer/2022042221/5ec7e4bde396e9508e2148aa/html5/thumbnails/22.jpg)
Choice properties
public Element Value { get; set;}
![Page 23: Building a FHIR client with HAPI and .NET (1)...Building a FHIR client with HAPI and .NET (1) ... • The standard specifies a RESTful API for interacting with that model • For example,](https://reader034.fdocuments.net/reader034/viewer/2022042221/5ec7e4bde396e9508e2148aa/html5/thumbnails/23.jpg)
Resource components
public partial class ReferenceRangeComponent : BackboneElement { … }
![Page 24: Building a FHIR client with HAPI and .NET (1)...Building a FHIR client with HAPI and .NET (1) ... • The standard specifies a RESTful API for interacting with that model • For example,](https://reader034.fdocuments.net/reader034/viewer/2022042221/5ec7e4bde396e9508e2148aa/html5/thumbnails/24.jpg)
Parsing/serializing
using Hl7.Fhir.Serialization;
import ca.uhn.fhir.context.FhirContext;
![Page 25: Building a FHIR client with HAPI and .NET (1)...Building a FHIR client with HAPI and .NET (1) ... • The standard specifies a RESTful API for interacting with that model • For example,](https://reader034.fdocuments.net/reader034/viewer/2022042221/5ec7e4bde396e9508e2148aa/html5/thumbnails/25.jpg)
The context (HAPI)
• The starting point for much of the HAPI-FHIR API is the FhirContext class
• FhirContext acts as a factory for the rest of the API, including the two parsers:
• XmlParser• JsonParser
• FhirContext is designed to be created once and reused (important for performance!)
![Page 26: Building a FHIR client with HAPI and .NET (1)...Building a FHIR client with HAPI and .NET (1) ... • The standard specifies a RESTful API for interacting with that model • For example,](https://reader034.fdocuments.net/reader034/viewer/2022042221/5ec7e4bde396e9508e2148aa/html5/thumbnails/26.jpg)
Parsing/serializing example Java
• s
![Page 27: Building a FHIR client with HAPI and .NET (1)...Building a FHIR client with HAPI and .NET (1) ... • The standard specifies a RESTful API for interacting with that model • For example,](https://reader034.fdocuments.net/reader034/viewer/2022042221/5ec7e4bde396e9508e2148aa/html5/thumbnails/27.jpg)
Parsing/serializing example C#
// Create a file-based reader for JSONJsonTextReader reader =
new JsonTextReader(new StreamReader(@"input.json"));
var parser = new FhirJsonParser();var new_obs = parser.Parse<Observation>(reader);
// Serialize an in-memory observation to an XML string
var serializer = new FhirXmlSerializer();
var xmlText = serializer.SerializeToString(new_obs);
![Page 28: Building a FHIR client with HAPI and .NET (1)...Building a FHIR client with HAPI and .NET (1) ... • The standard specifies a RESTful API for interacting with that model • For example,](https://reader034.fdocuments.net/reader034/viewer/2022042221/5ec7e4bde396e9508e2148aa/html5/thumbnails/28.jpg)
Working with REST
using Hl7.Fhir.Rest;
import ca.uhn.fhir.rest.client.api.IGenericClient;
![Page 29: Building a FHIR client with HAPI and .NET (1)...Building a FHIR client with HAPI and .NET (1) ... • The standard specifies a RESTful API for interacting with that model • For example,](https://reader034.fdocuments.net/reader034/viewer/2022042221/5ec7e4bde396e9508e2148aa/html5/thumbnails/29.jpg)
REST recap
• FHIR defines basic CRUD operations that can be performed on a FHIR compliant server (*not a complete list)
![Page 30: Building a FHIR client with HAPI and .NET (1)...Building a FHIR client with HAPI and .NET (1) ... • The standard specifies a RESTful API for interacting with that model • For example,](https://reader034.fdocuments.net/reader034/viewer/2022042221/5ec7e4bde396e9508e2148aa/html5/thumbnails/30.jpg)
Using the FHIR client
• See Publicly Available FHIR Servers for available test servers
C#var client = new FhirClient("https://vonk.fire.ly");
Java
![Page 31: Building a FHIR client with HAPI and .NET (1)...Building a FHIR client with HAPI and .NET (1) ... • The standard specifies a RESTful API for interacting with that model • For example,](https://reader034.fdocuments.net/reader034/viewer/2022042221/5ec7e4bde396e9508e2148aa/html5/thumbnails/31.jpg)
Clients: Two Distinct Flavours in HAPI FHIRAnnotation Generic/Fluent
public interface SampleClient extends IRestfulClient {
@CreateMethodOutcome create(@ResourceParam Patient thePatient);
@ReadPatient read(@IdParam IdType theId);
}
MethodOutcome outcome = client.create().resource(pat).execute();
● You create an annotated interface for your specific needs
● Similar to JAX-RS or Spring REST (but does not use these frameworks)
● Use chained method calls to do anything you need
● This is generally easier and more popular
![Page 32: Building a FHIR client with HAPI and .NET (1)...Building a FHIR client with HAPI and .NET (1) ... • The standard specifies a RESTful API for interacting with that model • For example,](https://reader034.fdocuments.net/reader034/viewer/2022042221/5ec7e4bde396e9508e2148aa/html5/thumbnails/32.jpg)
Clients: Two Distinct Flavours in HAPI FHIRAnnotation Generic/Fluent
public interface SampleClient extends IRestfulClient {
@CreateMethodOutcome create(@ResourceParam Patient thePatient);
@ReadPatient read(@IdParam IdType theId);
}
MethodOutcome outcome = client.create().resource(pat).execute();
Docs:http://hapifhir.io/ doc_rest_client_annotation.html
Docs:http://hapifhir.io/doc_rest_client.html
![Page 33: Building a FHIR client with HAPI and .NET (1)...Building a FHIR client with HAPI and .NET (1) ... • The standard specifies a RESTful API for interacting with that model • For example,](https://reader034.fdocuments.net/reader034/viewer/2022042221/5ec7e4bde396e9508e2148aa/html5/thumbnails/33.jpg)
Create interaction example Java
![Page 34: Building a FHIR client with HAPI and .NET (1)...Building a FHIR client with HAPI and .NET (1) ... • The standard specifies a RESTful API for interacting with that model • For example,](https://reader034.fdocuments.net/reader034/viewer/2022042221/5ec7e4bde396e9508e2148aa/html5/thumbnails/34.jpg)
Create interaction example C#
var pat = new Patient();pat.Name.Add(new HumanName()
.WithGiven("Homer").WithGiven("J.").AndFamily("Simpson"));pat.Identifier.Add(new Identifier("http://acme.org/MRNs", "7000135"));pat.Gender = AdministrativeGender.Male;
// Create a clientvar client = new FhirClient("http://vonk.fire.ly");
// Use the client to store a new resource instancevar outcome = client.Create<Patient>(pat);
// Print the ID of the newly created resourceConsole.WriteLine(outcome.Id);
![Page 35: Building a FHIR client with HAPI and .NET (1)...Building a FHIR client with HAPI and .NET (1) ... • The standard specifies a RESTful API for interacting with that model • For example,](https://reader034.fdocuments.net/reader034/viewer/2022042221/5ec7e4bde396e9508e2148aa/html5/thumbnails/35.jpg)
Searching
• FHIR defines a powerful search mechanism• Searches are specially crafted URLs to express queries such as:
• Find a Patient with the given Identifier• Find all Patients with given gender and DOB• Find all lab reports for a given patient identifier with an “abnormal”
interpretation
• Searching is powerful!• Learn about it at http://hl7.org/fhir/search.html
![Page 36: Building a FHIR client with HAPI and .NET (1)...Building a FHIR client with HAPI and .NET (1) ... • The standard specifies a RESTful API for interacting with that model • For example,](https://reader034.fdocuments.net/reader034/viewer/2022042221/5ec7e4bde396e9508e2148aa/html5/thumbnails/36.jpg)
Searching (2)
• For now, let’s imagine a search for a Patient named “Test” whose birthdate is before 2014
![Page 37: Building a FHIR client with HAPI and .NET (1)...Building a FHIR client with HAPI and .NET (1) ... • The standard specifies a RESTful API for interacting with that model • For example,](https://reader034.fdocuments.net/reader034/viewer/2022042221/5ec7e4bde396e9508e2148aa/html5/thumbnails/37.jpg)
Example search in Java
![Page 38: Building a FHIR client with HAPI and .NET (1)...Building a FHIR client with HAPI and .NET (1) ... • The standard specifies a RESTful API for interacting with that model • For example,](https://reader034.fdocuments.net/reader034/viewer/2022042221/5ec7e4bde396e9508e2148aa/html5/thumbnails/38.jpg)
Example search in C#
// Build a search and execute itvar q = new SearchParams()
.Where("name=Test")
.LimitTo(100);q.Add("birthdate", "lt2014-01-01");
Bundle results = client.Search<Patient>(q);
// How many resources did we find?Console.WriteLine("Number of results: " + results.Total);
// Print the ID of the first oneConsole.WriteLine("First result id: " + results.Entry.First().Resource.Id);
![Page 39: Building a FHIR client with HAPI and .NET (1)...Building a FHIR client with HAPI and .NET (1) ... • The standard specifies a RESTful API for interacting with that model • For example,](https://reader034.fdocuments.net/reader034/viewer/2022042221/5ec7e4bde396e9508e2148aa/html5/thumbnails/39.jpg)
Client interceptors (Java)
• Interceptors “wrap” each client operation and can:• Examine outgoing requests before they happen• Change outgoing requests before they happen• Examine incoming responses after they happen
• Interceptors implement the IClientInterceptor interface• For example:BasicAuthInterceptor and BearerTokenAuthInterceptor
• Add credentials to request
• See http://hapifhir.io/doc_rest_client_interceptor.html
![Page 40: Building a FHIR client with HAPI and .NET (1)...Building a FHIR client with HAPI and .NET (1) ... • The standard specifies a RESTful API for interacting with that model • For example,](https://reader034.fdocuments.net/reader034/viewer/2022042221/5ec7e4bde396e9508e2148aa/html5/thumbnails/40.jpg)
Adding headers to the request in C#
client.OnBeforeRequest +=(object sender, BeforeRequestEventArgs e) =>{
e.RawRequest.Headers.Add("some_key", "some_value");};
client.OnAfterResponse +=(object sender, AfterResponseEventArgs e) =>{
Console.WriteLine(e.RawResponse.StatusCode);};
![Page 41: Building a FHIR client with HAPI and .NET (1)...Building a FHIR client with HAPI and .NET (1) ... • The standard specifies a RESTful API for interacting with that model • For example,](https://reader034.fdocuments.net/reader034/viewer/2022042221/5ec7e4bde396e9508e2148aa/html5/thumbnails/41.jpg)
Questions?
![Page 42: Building a FHIR client with HAPI and .NET (1)...Building a FHIR client with HAPI and .NET (1) ... • The standard specifies a RESTful API for interacting with that model • For example,](https://reader034.fdocuments.net/reader034/viewer/2022042221/5ec7e4bde396e9508e2148aa/html5/thumbnails/42.jpg)
And now for some coding
Join us in the meeting rooms
![Page 43: Building a FHIR client with HAPI and .NET (1)...Building a FHIR client with HAPI and .NET (1) ... • The standard specifies a RESTful API for interacting with that model • For example,](https://reader034.fdocuments.net/reader034/viewer/2022042221/5ec7e4bde396e9508e2148aa/html5/thumbnails/43.jpg)