FHIR Bundle Visualizer

So a little while back I wrote about an app I developed during the WGM Connectathon to send an HL7 v2 message to a converter app, and display the response (a FHIR Bundle) in a number of visualizations after validating it using the community supplied validation tool (actually, exposed by the reference servers via the $validate operation). It occurred to me that this visualization might be of use to implementers who are developing query applications – such as the CSIRO Primary Care project for example, so I pulled it out into a separate application.

The app is available here  (I’ll hook it up to the main clinFHIR launch page at some point), and this is what the main screen looks like.


In the navbar at the top are the currently configured servers (set by clinFHIR in the usual way). The Conformance server is used for validation (via the $validate operation) , while the Data server is where bundles can be stored (we’ll come to that in a minute).

To the left is where bundles can be supplied. There are 2 options, each in a separate tab.

  • You can paste a bundle directly into the visualizer (click the ‘Import Bundle’ link and paste the bundle into the dialog that is displayed). Both XML and Json can be supplied. If you supply an identifier in the dialog, then the bundle will be saved on the Data Server and the identifier will appear in the bundle list (where all the ‘Document n’ entries are in the screen shot). As it’s saved on a public server, it can be selected any time – by any user of the app. (A good time to emphasise that there should be no real data in the bundle). This option is most useful when you already have a bundle from somewhere, and want to take a look at it.
  • You can also specify a query to run that returns a Bundle when selected. The query will be saved in the list, and is local to the browser – i.e. it won’t be available to other users / browsers. This is particularly useful when developing a query endpoint as you can specify the query to run, and then execute it whenever you want and view the results. (Note that the endpoint must support CORS as the query is from the browser)

However you specify the bundle, it is validated by the Conformance Server (It’s up to you to make sure the FHIR version of the Bundle and the conformance server are the same), and then a number of visualizations are presented which can be selected from the ‘visualizations’ tab.

The screen shot above shows the raw Json of the bundle (even if you supplied XML).

The ‘Bundle visualizations’ tab displays the individual entries in the bundle as shown in the screen show below.


The entries are in a list and show the resource type, fullUrl and number of validation errors (in the badge to the right).

Selecting an entry shows a number of sub views about that entry to the right

  • The Json of the entry element
  • A tree view of the resource
  • A graph of the resources that have a reference to or from the resource in the entry. The number in the graph is the number of validation errors.
  • The validation errors found for that resource

The graph tab shows a graph of all the resources in the bundle, as shown below:

Screen Shot 2019-06-01 at 10.17.22 AM

This can get quite complex for large bundles (which is why there is the other resource centered graph described above). Selecting a resource in the graph will display the Json of the entry containing the resource to the right.

The top Validation tab shows all results for the entire bundle.

If you want to use profiled resources rather than core ones, then there are a number of pre-requisites you need to meet (there are of the Validation routines – not the app).

  • The profile (StructureDefinition) that the resource instance should be conformant to must be on the conformance server – as must be all the Extension definitions (also StructureDefinitions) that it references.
  • The resource instance being validated must have a reference to the profile in its meta element (using the profile item).

Reach out in the clinFHIR chat (or comment here) if you have any questions/comments.


About David Hay
I'm an independent contractor working with a number of Organizations in the health IT space. I'm an HL7 Fellow, Chair Emeritus of HL7 New Zealand and a co-chair of the FHIR Management Group. I have a keen interest in health IT, especially health interoperability with HL7 and the FHIR standard. I'm the author of a FHIR training and design tool - clinFHIR - which is sponsored by InterSystems Ltd.

13 Responses to FHIR Bundle Visualizer

  1. Great job David.

  2. Ed Salvador says:

    If I send this or similar:
    GET http://localhost:9001/r3/Patient?family=chalmers&given=peter&gender=male&birthdate=“1974-12-25”
    (Of course, localhost:9001 would be replaced with the actual FHIR Server URL info)
    and get returned the following XML snippet:

    Then, I READ the XML and create another FHIR Server Query using the Patient ID received in the response above:
    GET http://localhost:9001/r3/Patient?id=fb4c9d01-734e-4f24-8dba-a2aed48a906b/%5BresourceType%5D?%5Boptional parameters]

    My question is:
    When I get the response to the FHIR Resource Query/Search, is there any way to link that to the Original Query/Search of:
    GET http://localhost:9001/r3/Patient?family=chalmers&given=peter&gender=male&birthdate=“1974-12-25”

    • David Hay says:

      Hi Ed – what kind of link are you after? Generally the RESTful queries themselves don’t share state at all so there’s no direct link (other than that the patient was in the previous bundle… BTW – the second query doesn’t look right – id should be _id (which will return a bundle containing just that resource) or Patient/{id} which will return the Patient resource directly. Not sure what the other parameters are intended to do…

      • Ed Salvador says:

        We are attempting to receive a request from our practices that contain the patient demographics (ie. HL7 ADT, etc.) with their internal Patient ID. We will then convert that into a FHIR GET to receive the Patient ID of the FHIR Server. We would then use the FHIR Server Patient ID to get FHIR Resources. (The Query for FHIR resources was just an example and will be formatted correctly). When we receive the FHIR Resource(s) we need to transmit (or make available) to the original requesting practice the FHIR Resources received from the FHIR Server.

  3. David Hay says:

    This sounds like a good question to post to the zulip chat and get wider community input. If I understand the requirements correctly you have a FHIR server (or at least a repository that can create FHIR resources and you’re wanting to respond to a query for data that comes as an HL7 v2 message, and return a bundle of FHIR resources. Sounds like a job for an integration engine.

    Would it be possible to have your clients use REST instead? Might make for a tidier interface, though I suspect you will still need some server side logic to ensure that the initial query matches a single patient…

    • David Hay says:

      BTW – the discussion of $everything in the spec might be of use – and _include…

    • Ed Salvador says:

      David – It seems that I was not clear in my question.
      For example: If there is a hospital that is using EPIC as the EMR and FHIR Server). And one of our practices needs to get clinical information from the hospital. We are acting as the Hub/Gateway. So, the practice sends us the patient demographics ( Hl7 ADT, etc.- they do not have the Patient ID that the hospital uses). We transmit the FHIR GET to receive the Patient ID of the hospital (FHIR Server). The hospital returns the Patient ID of the hospital (FHIR Server). We then use the hospital Patient ID to do a GET of FHIR Resource(s). We then need to transmit/make available the FHIR Resources received from the hospital to the originating requestor practice.

      • David Hay says:

        OK – but if you are the gateway, can’t you maintain the ‘link’ there? ie

        1. client -> gateway with request
        2. gateway -> EHR to get patient identity. If not exactly 1 match then return to client with error
        3. gateway -> EHR to get patient data
        4. gateway -> client with data

        In an integration engine like Rhapsody (which I’m associated with) this would be a fairly straightforward route and I’m imaging that you should be able to do the same…

  4. Ed Salvador says:

    I understand, your steps 1-3.
    However, if you have several practices making requests to the same FHIR Server( ie. through the Gateway) how do you distinguish which client is making which request? (Step 4 in your response).

    • David Hay says:

      The state needs to be held in the gateway… – the mechanism for that will depend on the gateway capabilities – I’ve done a few node-red posts that shows a similar process – ie multiple steps in sequence with decision points along the way…

  5. Ed Salvador says:

    Thank you for your information and your help.

  6. David Hay says:

    You’re welcome! And good luck…

Leave a Reply

%d bloggers like this: