Tuesday, 12 March 2013

FHIR - Feel The 'Fire' - 1 (FHIR Client)


First thing that I wondered after hearing about FHIR is “What is a Healthcare Resource?” and very simple answer is available in FHIR specification (http://www.hl7.org/implement/standards/fhir/ ).

Second thing I wondered was “What does it look like?” and there are many examples available in FHIR specification. But as a beginner on FHIR I started comparing it with HL7 v2.x (on which I have implemented many projects) and this created some confusions.
I found FHIR concept a reall simple but it was difficult to understand implementation and real interoperability scenarios in RESTful environment without doing some hands on with test servers:
  1. Connect with test servers available & feel the resources using (Covered in this post)
    1. Fiddler (http://www.fiddler2.com/fiddler2/ )
    2. Your own client in C#
    3. Using XmlHttpRequest
  2. Implement a simple REST service with http GET and expose a healthcare resource (will cover this in my next post)
    1. Patient resource collection feed

I think after doing this, you will have fair idea about FHIR, healthcare resources and interoperability using FHIR.

Let’s start by connecting FHIR test servers

Note: A detailed presentation with screenshots is available at http://www.slideshare.net/j4jayantsingh/fhir-feel-the-fire-1
http://wiki.hl7.org/index.php?title=Publicly_Available_FHIR_Servers_for_testing lists all the publically available test servers. In this post I will connect to Grahame's test server. You should try all the available. (Note that these servers are testing servers. They may be sporadically unavailable)

Connect Test Servers using Fiddler

Open Fiddler and compose a new resource request. As first step we will request a conformance resource to know how an application or implementation supports FHIR.
Compose this request: OPTIONS http://hl7connect.healthintersections.com.au/svc/fhir/
You can view the raw xml/json data in fiddler and explore the details of a resource.
Some other simple resource requests would be:
GET http://hl7connect.healthintersections.com.au/svc/fhir/patient to get Patient Resource Feed
GET http://hl7connect.healthintersections.com.au/svc/fhir/patient/@1 to get Patient id 1
GET http://hl7connect.healthintersections.com.au/svc/fhir/document to get Document Resource Feed
Let's try to find a resource which doesn’t exist on server
GET http://hl7connect.healthintersections.com.au/svc/fhir/document/@123456 this will return HTTP 404 Not Found

Connect test servers with your own client in C#

Now, let’s create simple desktop client in C# which will work similar to fiddler, but writing a client on your own will provide you better understanding of FHIR & RESTFul approach.
In this client I will just provide a mechanism to call a RESTFul resource and display result in raw (xml/json) format. Once we have the data in xml/json we can parser it the way we want. This application uses a library called RestSharp.
Following is the code with comments to help you understand

 //create a RestClient  
 var client = new RestClient();  
 //Assign base url of RESTFul Server  
 client.BaseUrl = "http://hl7connect.healthintersections.com.au/svc/fhir/";  
 //HTTP method(GET/POST etc) to use for this request  
 Method method = (Method)Enum.Parse((typeof(Method)), cmbHttpOptions.Text);  
 //Create RestRequest  
 request = new RestRequest(method);  
 //Add header "Accept" to request xml or json data format  
 if(cmbContentType.Text.Equals("xml"))  
   request.AddHeader("Accept", "application/xml"); //use text/xml+fhir  
 else  
   request.AddHeader("Accept", "application/json"); //use application/json  
 //resource to query like patient, patient/@1, document etc.  
 request.Resource = "patient/@1";  
 //Execute the request and get response  
 IRestResponse response = client.Execute(request);  
 //display the raw response header  
 txtResult.Text = "************Response Header***********\n"  
 for (int i = 0; i < response.Headers.Count; i++)  
   txtResult.Text += response.Headers[i].Name + ": " + response.Headers[i].Value + "\n";  
 txtResult.Text += "StatusCode: " + response.StatusCode + "\n";  
 //display the raw response content  
 txtResult.Text += "\n\n************Raw Content**********\n";  
 txtResult.Text += response.Content;  


Connect test servers with your own client in HTML using XmlHttpRequest

This code will tell you how simple it is to play with healthcare resources in FHIR. It just need HTML & javascript knowledge to understand this code and start requesting FHIR resources from FHIR servers.
Please note: your might have to clear browser cache to view the effect of Content-Type(xml/json)
 <!DOCTYPE HTML>  
 <html>  
 <head>  
 <script language="javascript">  
 var oXmlHttpReq = new XMLHttpRequest;  
 function processRequest()  
 {  
  try  
  {  
   document.getElementById("txtResult").value = '';  
   if (oXmlHttpReq != null) {  
    var uri = document.getElementById("txtUri").value;  
    var method = document.getElementById("selMethod").value;  
    var contentType = document.getElementById("selContentType").value;  
    oXmlHttpReq.open(method, uri, true);  
    oXmlHttpReq.setRequestHeader('Accept', contentType);  
    oXmlHttpReq.send();  
   }  
   else {  
    alert("AJAX (XMLHTTP) not supported.");  
   }  
  }  
  catch(e)  
  {  
   alert(e.message);  
  }  
 }  
 oXmlHttpReq.onreadystatechange = function() {  
  try  
  {  
   if (oXmlHttpReq.readyState == 4) {  
    if (oXmlHttpReq.status == 200) {  
     var result = document.getElementById("txtResult");  
     result.value=oXmlHttpReq.responseText;  
    }  
    else  
    {  
     alert('req status: ' + oXmlHttpReq.status);  
    }  
   }  
  }  
  catch(e)  
  {  
   alert(e.message);  
  }  
 }  
 </script>  
 </head>  
 <body>  
 <select id="selMethod">  
  <option value="GET">GET</option>  
  <option value="OPTIONS">OPTIONS</option>  
 </select>  
 <input type="text" id="txtUri" size="80" value="http://hl7connect.healthintersections.com.au/svc/fhir/patient" />  
 <select id="selContentType">  
  <option value="text/xml">application/xml </option>  
  <option value="text/json">application/json</option>  
 </select>  
 <button id="btnGo" onclick="JavaScript:processRequest();">Click Me!</button>  
 <br/>  
 <textarea id="txtResult" rows="35" cols="100" > </textarea>  
 </body>  
 </html>   

Please try playing around with more resource URIs and explore FHIR. Reference Implementation available with FHIR specification provides classes to parse this xml or json data received from FHIR test server.
In second part of this post I will provide a sample WCF REST service and expose a "Patient" resource, a GET on Patient resource will return Patient Resource Feed.

Comments:

I appreciate honest (positive/negative) feedback.

Source Comment
Email Ewout Kramer on 27th March 2013

use text/xml+fhir for the xml format of Resources, and application/json otherwise

Furthermore, once you start transferring atom feeds, we use application/atom+xml or application/json (so this last one is the same as for individual resources!)

Sample Immunization Records Blockchain using Hyperledger Composer

This is basic and sample Blockchain implementation of Immunization Records using Hyperledger Composer.  Source Code available at:  https...