IHE MHD (Mobile Health Data) and FHIR

Just noticed John Moehrke’s post on the recent IHE MHD connectathon. I love the way that this shows how the different organizations involved in healthcare interoperability are working together rather than taking opposing views…

FHIR XDS: revisiting the patient identity.

While at the HINZ conference this year, I was at dinner with Grahame and ‘Friendly FHIR’ (your identity is safe with me), and we were talking about the roles of the Identity Source and XDS Registry in the context of a FHIR XDS implementation. In previous posts I had indicated that the Identity Source could simply expose a FHIR Patient endpoint – and that is still an option for general use – but in the case of the XDS Registry, Grahame pointed out 2 issues with that approach:

  • If the XDS infrastructure is heavily used, then the load on the Identity Source is going to be high
  • Merged patients are an issue because DocumentReference resources in the registry will continue to have references to patients that have been merged with another and it needs to return all references to all merged patients when responding to a query for a single patient.

So, the registry really does need to maintain it’s own store of patients – though this is really a specialized ‘cache’ that is only updated by the Identity Source. This also means that there is really no need for a Document Consumer to access the Identity Source directly – at least in the XDS context – which is a bonus.

We’ve talked before about how FHIR represents merged patients (Actually, just checking the specs I note that there is now a link type property that must be set to ‘replace’ to indicate the merge), so I won’t repeat that here, but it is worth thinking about how this could all work in the context of an Identity Source needing to update an XDS Registry.

The requirement is that when there are changes to patient information at the identity source, then that needs to be communicated to the XDS registry somehow. We don’t need all the patient details all of the time – the more we store then the greater the volume of updates –  but we probably want the ID, the links, the identifier information and the basic name/Date of Birth/Gender stuff. We would want to be notified about:

  • new patients
  • changes to the patient data we are storing
  • any merges

The XDS registry then needs to maintain an internal data store of some sort that maintains those links between patients so that when a document consumer queries the registry, all the DocumentReference resources for that patient and any patients merged to it are returned as well. (And note that each DocumentReference resource will continue to refer to the Patient it was associated with at creation time – it is the patient that is merged and not the other resources that refer to it).

There are a couple of ways we could do this:

  • Either the Identity Source could push changes to the XDS registry as they occur (a ‘push’ model)
  • Or the Registry could periodically request changes from the Identity Source. (a ‘pull’ model).

Lets consider the push model first.

When the Identity Source merges a patient with another, there are 2 Patient resources to change:

  • The Primary resource (the one you want to keep) has a reference to the secondary resource (that is being replaced) with a link type of ‘replace’.
  • The Secondary resource has a link back to the primary (also with a type of replace) and has it’s ‘active’ property set to false.

As these really need to be managed as a transaction, then the Identity Source places the two resources in a bundle and either:

  • Posts it to the root of the XDS registry
  • Or (and this is probably more explicit) the XDS registry exposes a service (maybe /service/patient/merge) that takes the bundle of resources

In either case, the registry updates its data store. It might return an OperationOutcome resource to indicate the outcome.

So that is the push from the Identity Source to the XDS registry – how would the pull model work?

Well, because FHIR is built using standard internet type technologies, there’s a pre-existing standard that is intended for communicating changes and updates between systems, and that is the Atom feed – which we’ve seen used as the bundling mechanism when we want to move multiple resources around.

In this use, we’re implementing a ‘pub/sub’  architecture where the client (the XDS registry) subscribes to a feed of changes published by the Identity Source. Reviewing the spec, we note that the history operation allows a server to publish changes for a specific resource, a type of resource, or all resources on that server. In our use case, we’d go for the middle option – we want a feed from the Identity Source that publishes all changes for any Patient resource.

So what happens is something like this:

Periodically the XDS registry issues a GET request to the Identity Source like this:

GET /identityServer/Patient/_history?_since=<dateLastQueried>

This will return a bundle containing all the changed resources since the last request. The registry can then process the Patient resources in that bundle and update it’s internal data store as required.

So which pattern to choose? Well, that depends on your implementation.

The ‘classical’ XDS way is the push from Identity Source to Registry, and that is probably the simplest  (though in practice you might want to put an integration engine in the middle so the Identity Source doesn’t need to be concerned with communication issues – and could support other systems that maintain patient caches).

However the pull feed option might be useful if there are multiple clients needing updates, of if that technology is already supplied by the Identity Source.

Hopefully that finishes off XDS stuff for a while, because I’d like to start thinking about FHIR documents…

Getting documents from a FHIR XDS infrastructure

So far in our little mini series on FHIR and XDS we’ve had an overview of how FHIR resources support a document sharing infrastructure, looked at how a document creator can create and submit documents to a repository and/or registry, and spent a bit of time talking about the DocumentReference resource.  Time to think about the consumer of these services.

There are 2 main scenarios that we want to support:

  • Getting a list of documents for a patient (with various search parameters – e.g. a date range, type of document etc.) and displaying the metadata in a list to the consumer
  • Retrieving a particular document to view

Getting the list of documents

Let’s think about the first scenario, and to keep it simple we’ll aim to retrieve all the documents for a patient. Given that the metadata about the document is represented by a DocumentReference resource hosted by the registry server we are using, then this is obviously going to be a query against the DocumentReference endpoint. There are a couple of ways we could to this, and the way we choose depends on whether the have the patients ID or their identity (in fact, it’s exactly the same issue as the document creator had – so refer to that post for more discussion on this).

If we know the patient ID (let’s say it’s 100), then our query will be something like:

GET  http://registryserver/DocumentReference?subject= 100

(assuming that the patient identity is also on the registry server – if not then the patient ID would need to be the absolute reference to the patient resource).

If we don’t have the patient ID, but we do have an identifier (e.g. PRP1660) then we have a couple of options (as always!):

  • Look up the patient ID by a query against the Patient endpoint first
  • Query the DocumentReference with the patient identifier using a chained query, like so:

GET http://registryserver/DocumentReference?subject.identifier= PRP1660

Note that the server is not obliged to support chained queries – check their conformance resource to see if they do. Also, I didn’t include the identifier system in the query – depending on the implementation I may need to do so. Chained queries make a clients life easier (but a servers life harder) – but as the FHIR philosophy is to make it as easy for clients as possible, it’s to be hoped that servers do support that capability.

In either case, the result will be a bundle of DocumentReference resources – the difference between the two being that if we specified the patient ID, then we know that all the DocumentReference resources are for the right person. If we used the identifier, then we are trusting that the identifier is unique (which means that we should probably not be lazy and include the system in the query).

But what if we want a more targeted search? Perhaps we’re only interested in documents created in the past year, or only outpatient summaries?

Well, checking the defined search parameters for DocumentReference we see a period parameter (date of the service) and a type parameter (document type) which would seem to suit our purpose, so (assuming we have the Patient ID):

GET  http://registryserver/DocumentReference?subject= 100&period= >= 2013-01-01


GET  http://registryserver/DocumentReference?subject= 100&type= http://loinc.org|34108-1

And of course we can mix and match parameters as we need to (provided the server supports them as documented in their conformance resource)

Retrieve a particular document.

So now we have a list of documents which we can display to our user, how do we retrieve a particular document for them? Well, hopefully the DocumentReference resource that describes the document we want has the location property. Then it’s just an HTTP call away. If the repository where the document is stored doesn’t support a direct GET, then you’ll need to drop back to the XDS ‘Retrieve Document’ profile, the access details for which should be on the DocumentReference.service property.

Assuming you can make a GET call, the repository should include the HTTP standard headers in the response like content-type (which is also recorded in the DocumentReference.mimeType property of course), so rendering by the viewer should be straightforward. Of course, it can get a lot more complex than that – especially in the case of a structured document like a CDA or FHIR-document, when specialized client-side renderers (like XSLT stylesheets) will be required. The metadata in the DocumentReference resource (and possibly HTTP headers)  should indicate what renderer is going to be needed, so all should be well.

Note that the GET call will return the document directly, whatever it is – eg a PDF or CDA document – not a FHIR resource of any sort.

A short (and grossly incomplete) comment on FHIR security.

FHIR itself doesn’t define security protocols – rather it provides the ‘hooks’ that a security framework can use when deciding whether to deliver up a particular document – or even whether to include the document metadata in the original list of documents.

There is an assumption that anyone accessing any of these services is authenticated (identified) and oAuth is the recommended (though not mandated) way to do this.

FHIR supports the concepts of tags – that can be applied to any resource, and allow a privacy policy framework to apply rules when determining whether to deliver up information p and those rules can become arbitrarily complex.  In addition, the DocumentReference resource has the specific confidentiality property that can also be used.

There is also the SecurityEvent resource (analogous to the IHE ATNA profile) that can be used to record significant events such as the release of a document to a viewer. This resource can then be used as the basis of functionality such as “Who has viewed my data?”, and can be created at any time that is appropriate in the overall workflow. The provenance resource indicates the context in which a resource was obtained – e.g. the person who created it.

So, it is the responsibility of the governing body for the document sharing infrastructure to make these policy decisions – and to enforce them! And the IHE ‘Affinity Domain’ concept is a good source of information.

Incidentally, for health security issues in general, check out John Moehrkes blog as a good source of inspiration!

We’re getting towards the end of our little mini series – one of the longer ones so far! We’ll wrap up the loose ends in the final post – in particular we need to think about the best approach when a document source needs to update a document it has already sent to a repository.

FHIR and XDS – an Overview

One of the ‘sweet spots’ for FHIR is establishing RESTful interfaces to an IHE XDS (Cross Enterprise Document Sharing) implementation. IHE had already started down this path when it created the ‘Mobile Access to Health Documents’ – MHD – profile as a way of making it easier for mobile devices to access XDS installations, but with the emergence of FHIR, the two efforts have been merged and the intention is that the MHD version 2 profile will be FHIR based. This is not to say that FHIR can replace XDS – there are circumstances where the native XDS interfaces can be required – especially in larger deployments, but the ease of use of FHIR makes an attractive façade in many situations.

It should also be mentioned that it is quite feasible to implement an ‘XDS-like’ system that follows the overall pattern of XDS, but doesn’t have an XDS ‘back-end’ if it meets the use cases.

This will be the first in a series of posts that talks about implementing the FHIR as a front end to XDS, and will be an overview to XDS and how FHIR resources match the profile.

For those who are not familiar with XDS, its purpose is to enable the sharing of documents between healthcare enterprises. The image below is the standard representation of XDS:


It shows 5 principal actors:

  • The Document Registry that is the ‘index’ to available documents. Within a single implementation there is only a single registry, though there are profiles (like XCA) that support ‘inter-registry’ queries where there are multiple co-operating deployments
  • One or more Document Repositories that actually hold the documents
  • Multiple Document Sources that actually create the document, and submit them to a repository
  • Multiple Document Consumers that query the registry for documents, and then retrieve the documents from the indicated repository
  • A single Identity Source, that manages patient identity

There are a number of transactions defined, and the ones that are of interest to us are as follows:

  • Register and provide document set (ITI-41), where a document source assembles a package containing 1 or more documents, with associated metadata (which we’ll talk about shortly) and sends that to a repository for storage.
  • Register document set (ITI-42) where the repository forwards the metadata to the registry.
  • Registry stored query (ITI-18) which is the consumer making a query of the registry to retrieve specific documents based on some search criteria.
  • Retrieve document set (ITI-43) defines how a consumer retrieves a specific document. Generally, this will be after they have queried the registry.
  • Patient Identity Feed (ITI-8, ITI-44) shows the identity source updating the registry with demographic information about patients – especially ‘merges’ where a single patient is known by more than one identifier.

Refer to the XDS profile for more details.

Applying  FHIR resources to this picture, gives us the following:


We can see that there is a good match (not unsurprisingly) between the XDS transactions & the FHIR resource end points.

  • A document source can submit the document and metadata to the repository via a transaction (like the medication update)
  • The repository updates the registry by posting a resource to the registries DocumentReference endpoint
  • A Consumer searches for documents via a query against the registries DocumentReference endpoint, and retrieves the document via a GET against the repositories /binary endpoint.
  • A SecurityEvent resource that records accesses of significance.

Note that for the purpose of this discussion (to keep things simple), we are ignoring the DocumentManifest resource, and only using the DocumentReference resource – which means that we will only be submitting and retrieving a single document at a time. The DocumentReference resource describes the metadata (and supplies the base data for searching) for a single document. The DocumentManifest resource ‘groups’ multiple documents (for example a document and an attachment) into a single package. We’ll come back to this in a later part of this series.

It’s also possible for the document source to update the registry directly. They may do this if the document is being stored outside of the XDS infrastructure (e.g. to support a repository that is not otherwise functioning as an XDS repository). We’ll also touch in this later on.

We’ve talked about a ‘document’ quite a lot – but what is a document? Well, in regards to this discussion it’s pretty much anything you need it to be – the spec states:

A document is some sequence of bytes that is identifiable, establishes it’s own context (e.g. what subject, author etc), can be displayed to the user, and has defined update management

It could be a CDA, a PDF, a text file, a FHIR document or even a Microsoft Word document. It’s the DocumentReference that has the metadata about the document – which includes the format of the document (as the mime type)

The last thing that we’ll touch on in this introduction is the concept of the Affinity Domain. IHE defines the affinity domain as “a group of healthcare enterprises that have agreed to work together using a common set of policies and share a common infrastructure”

In practice this includes things like:

  • The security & privacy policy that members will adhere to
  • Confidentiality codes & their meanings
  • What are the document ‘types’ and ‘sub-types’ – e.g. LOINC codes for things like ‘Patient Summary’, ’Discharge Summary’, ‘Clinic Note’ etc.
  • The supported document formats – eg the mimeType or more detailed descriptions
  • What are the possible statuses that a document can be in
  • The types of facility that are recognised (Primary Care, Hospital, Rest Home)
  • Clinical service (Orthopaedic, Paediatric, ED…)

There are other characteristics that can be applied to a document, but these are the most important that the affinity domain needs to agree on.

In the next post, we’ll dig into how the client sends a document to the server.