Getting more than one type of Resource back in a FHIR query

I received an interesting question from a colleague at Orion Health today:

We’re looking at the Appointment API for FHIR for some upcoming work (http://fhir.azurewebsites.net/appointment.html).

The location (http://fhir.azurewebsites.net/location.html) of the appointment is a reference link in the API example, and we want to show that information in the list of appointments for the patient. With the current modelling I think that means we’d have one REST API call for the list and then a REST API for each appointment to get the location information. Do you know if there is any provision in FHIR for being able to “inline” the reference information for lists of content to reduce the number of HTTP requests necessary to obtain and present the information?

This is an interesting question, and one that has a number of solutions.

First – what is not: Contained resources. This was actually the subject of my very first post and you can read the details there, but briefly, contained resources are intended for situations where it is not possible to properly identify a resource – which is clearly not the situation here.

We’ll have a look at 4 possibilities (and there may be more):

  • The display property
  • The _include query parameter
  • A compartment
  • A custom service

The display property is the simplest solution. It is intended to identify what is being referenced (in this case a location resource) and is not a copy of the resource contents. The idea is that it should be enough to display in a list or some other display to the user – so would seem a good fit here. The downside is that it is populated by the resource creator, and may not have all the information that the consumer wants to display.

Next up is the _include query parameter. This allows the consumer to request that the server include other resources in the query, based on a query parameter. So the following query would ask that the server include in the response bundle the Location resources that are referenced by the Appointment resources that match the query

GET /Appointment?participant.individual={patientID}&_include=Appointment.location

The third possibility is the patient compartment. This is really a form of ‘syntactic sugar’ that allows queries to be more naturally expressed. So:

GET /Patient/{patientID}/Appointment?_include=Appointment.location

(btw – I’m not completely sure that this will work as the patient is not a single property. I’ll update the post if there are changes)

And finally, it would be possible to create a custom service – though with the options above, this doesn’t seem necessary, and these are really more intended where there is some business or task based logic to perform.

Note that only the first option is a core part of the FHIR spec – the other options depend on the server implementing them.

So there you go!

And if you are interested in the Appointment resource, now would be a good time to go and comment!

FHIR resources in specific scenarios

Taking the example of Grahames ‘Q&A’ format, the following question was asked on the FHIR List forum:

Based on what I have seen, FHIR defines a set of resources and all possible relationships between resources, but doesn’t define which/how resources should be used in a particular scenario – the latter needs to be defined as a Profile. And FHIR per se doesn’t have Profile recommendations for any scenario. Implementers need to define their own Profiles and figure out how systems interoperate on a semantics level. 

and answered by Lloyd:

Sort of.  First, FHIR doesn’t actually define all possible relationships between resources.  It merely defines the “common” ones – those deemed to be within the 80%.  Many other types of relationships are possible through the use of extensions.  (E.g. encounter is associated with a single patient in the core resource, but with extensions could support multi-patient “group” encounters, for example)
 
You can approach interoperability with FHIR in a couple of ways.  In one approach, you just expose everything you do as a FHIR resource and anyone who wants to consume your content can simply pick and choose from what you expose (whether as a dump in a bundle or by hitting your FHIR REStful service).  In the second approach, you expose a particular subset of content (or perhaps even enhance the capability of your system to support additional data elements) as defined by a particular profile on FHIR.  These profiles could be created by a variety of groups.  Some (e.g. a FHIR equivalent of CCDA) will likely be created by HL7 international.  Some may be produced by IHE or other international SDOs.  Some will be created by HL7 affiliates and national programs.  Some will be created by large healthcare organizations.
 
The creation of profiles will take time and will be driven by specific use-cases.  They don’t yet exist.  So for early adopters, you sort of have to either take the first approach or go through the process of creating your own profile, ideally with a group of like-minded early adopters.  If you’re taking the second approach, you need to identify the area of healthcare that you’re targeting, look at existing capabilities and business needs.  Inpatient care and Outpatient care look quite different.  (So does human vs. veterinary or individual vs. public health.)  That’s why your initial question of identifying the “minimum” is so challenging to answer.  The minimum depends very much on what area of healthcare you’re targeting, what problem you’re trying to solve and even what country/region you’ll be working in.

I thought it was worth sticking it up here so I can find it later! Profiles are going to be important…

Decomposing a FHIR document

Scenario 2.3 of Connectathon talks about a server ‘decomposing’ a FHIR document. This is another of those huge topics, as it is all about using the document as a ‘carrier’ for information that is used by a recipient to update their own data stores, rather than simply storing it as a ‘blob’ to be displayed to a user on request.

The issue is not so much a technical one – that’s relatively straightforward (though one of the more complex in FHIR) – but rather relates to the purpose of a document as a ‘summary at a point in time’ – or as a ‘snapshot’, rather than a mechanism to ‘transfer state’.

Read more of this post

Retrieving and rendering a FHIR document

This post is going to be a bit of an anticlimax.

Once we’ve created the FHIR document and saved it via the /mailbox entry point, then we probably want to be able to find it again at some stage (assuming that the reason we saved it was to make it available to others of course). Well, because the server created DocumentReference resources during processing, then we just need to follow the same process that we used when discussing how to retrieve CDA documents using XDS principles – i.e. query the DocumentReference end point, and then get the document using the location property of the individual DocumentReference resource.

Read more of this post

Server processing of FHIR documents: Connectathon

In this post we’re going to think a bit about how the server might process a document that it receives. This is a massive topic, and certainly not one that can be covered in a single post – or by any one individual! Apart from anything else, there are lots of different possibilities – all legitimate in specific circumstances.

This is an important concept for FHIR – it doesn’t seek to drive any particular design or architecture – rather it attempts to support how data is moved around now, and how it may be done the future. It’s up to individual implementations to decide the details, but using common ‘building blocks’.

Read more of this post

Creating a FHIR document for the January Connectathon

I had intended to talk in some detail about the Composition resource next, as this is one of the key resources for a FHIR document, but because the January connectathon is getting close I’m going to do a series of posts to directly support people attending connectathon, and wanting to experiment with the document track. I’m planning 4 posts in this series:

  • How a client would create a FHIR document (incidentally for the remainder of this series, I’m going to refer to a FHIR document just as  ‘document’, so when you see this, I’m NOT talking about CDA. Later posts will talk more about the relationship between the two).
  • How a server could process a document. There are a few possibilities…
  • How to find the document on the server later, and render it to the client.
  • A wrap up on the Composition resource and anything else left over.

I do intend to spend a lot more time on FHIR & CDA, but this should at least cover the basics.
Read more of this post

FHIR: meet #CDA

CDA (Clinical Document Architecture) is undeniably the most successful HL7 version 3 standard. It’s being used very widely around the world for representing clinical data, and is one of the core standards for many jurisdictions – like Meaningful Use in the US. Obviously, if FHIR is to succeed, then it needs to have some way of doing what CDA does now (and including all the good thinking that has gone into CDA).

Another reason to start thinking about CDA is that the next FHIR connectathon at the January Working Group Meeting next year is going to have FHIR documents as one of the themes, so it makes sense to start thinking about how this all works.
Read more of this post

More thoughts on notifications in FHIR

I’ve been thinking a bit more about notifications since my last post about wanting to alert the patients usual GP (General Practitioner) that there is a document generated as a result of an ambulance visit for them to review. In particular, I’ve been thinking about other scenarios where a sender not only wants to inform a recipient that there is a document for them, but also that there is some action that needs to be performed for the patient. There’s a relationship of some sort to Tasks as well…

Looking at some sample scenarios where the recipient is a GP:

  • The ambulance visits a patient after a fall and delivers them to hospital where they are admitted. The notification to the GP is just an FYI (for your information), and there is no expectation of action.
  • The ambulance visits a patient with asthma and nebulizes them. They do not need to go to the hospital, but should be reviewed the following day.
  • A hospital discharges a patient having started them on warfarin. The GP is requested to repeat an INR in 5 days and adjust the dose if required.
  • A patient visits a private ‘after hours’ service with a lacerated hand. The service sutures the wound and asks the GP to review the patient in 5 days to remove the sutures.
  • A patient is seen by an out-patient clinic and their anti-hypertensive medication adjusted. The GP is requested to monitor the Blood Pressure to endure that they don’t become hypotensive.
  • While in hospital for a routine appendicectomy, an elevated Glucose blood result is noted. The GP is asked to follow up to investigate the possibility of diabetes.
  • A District Nurse visits a patient to dress a wound, and notes that the Blood Pressure is high.

In many (but not all) of these scenarios, there is an expectation by the sender that the recipient GP is going to do something. So in those cases the sender really needs some way of knowing whether:

  • The GP has received the request and will perform the requested action
  • The GP has received the request and will not perform the requested action (maybe it was the wrong GP)
  • The GP never received the request at all.

(I appreciate that this overlaps with some other important concepts like ‘Transfer of Care’, ‘Care Plan’ or ‘Tasks’, but for the sake of this discussion I’m going to keep it simple and just focus on the interaction between sender and recipient).

So let’s extend the simple concept of a Notification and add a few more properties:

  • Expected action. This is optional – if not present then the Notification is an FYI. We’ll make this a CodeableConcept so we can define common set of actions if we want to, which might be good for reporting, but also supports plain text, which will be the most likely early on. We’ll make this multiple to cover the situation where there is more than one thing needed to do by the recipient. If there were multiple actions my different recipients, then we’d use separate Notifications for each recipient.
  • Date due. This only makes sense when there is an expected action, but gives the recipient some idea of when the requested follow-up should occur.
  • Recipient Status. This will be used to manage the state of the Notification – I’ll talk about this in a moment. It will be a code datatype, with a fixed set of values.
  • Recipient Status Comment. A General comment field.

That takes care of the properties of the Notification, but we need to figure out how to manage the workflow aspects of the process – as described above, how can the sender be sure that the GP will carry out the requested actions (or not)?

We’ll use FHIR’s versioning capacity – plus the Provenance resource – to do this. (There may well be better ways, but let’s see how this plays out). It’ll work something like this:

  1. The sender will create the Notification resource (actually an e Other resource, as there is no specific FHIR resource for notifications yet) , setting the recipient details plus the expected action and date due. The recipientStatus will be ‘waiting’
  2. The recipient will periodically poll for Notifications with a recipientStatus of waiting – This will be slightly different from the version in the last post, because it will always return waiting notifications. Note also that we are using th
GET [server]/Other?code='notification'&recipient={gp}&recipientStatus=waiting
  1. The recipient can then update the Notification resource, setting the recipientStatus to ‘accepted’ or ‘declined’. They can use the RecipientStatusComment for any comment they may need to make – e.g. the reason why the GP declined to accept the action. If it is necessary to be more explicit about the person making the change, then they can create a provenance resource that has that information (the easiest way to do this is to put the updated Notification & Provenance resources in a bundle as discussed in previous posts)
  2. Optionally, once the action has been completed, the RecipientStatus can be updated to completed.

The sender can then monitor the status of the notifications as required.

Notifications where the recipient has declined the action:

GET [server]/Other?code='notification'&author={sender}&recipientStatus=declined

Notifications that have not been reviewed by the recipient yet

GET [server]/Other?code='notification'&author={sender}&recipientStatus=waiting&dateCreated< {yesterday}

To get a full picture of all changes to a Notification, we will need 2 queries:

The history of changes to the Notification resource

GET [server]/Other/{id}/_history

The Provenance resources that are associated with the Notification

GET [server]/Provenance?target={notificationID}

Of course, if we were being a nice server, we’d bundle both of these into a simple service that would make the calls internally and return a bundle of resources that would contain all the versions of the Notification resource, plus any Provenance resources associated with them.

GET [server]/Service/Notification/{notificationID}/_history

This pattern might not be suitable for a more fully featured task management solution, but it would seem the be sufficient for the simple use cases that we identified above.

So the complete list of properties for our improved Notification resource is (and remember that this is actually an Other resource at this stage, and all the properties are extensions):

  • Code
  • Subject
  • Author
  • Date Created
  • About
  • Recipient (was Target)
  • Expected action
  • Date due
  • Recipient Status
  • Recipient Status Comment

Comments welcomed!

FHIR interfaces to existing systems

Just a quick note about some work that is being done by Robert Worden (HL7 UK) on methodologies and tooling for creating FHIR services against existing back end systems. He has developed a system that uses configuration rather than code to map between the internal structures of the back end system and the FHIR service which is an interesting approach.

More detail here, which has a sample interface, plus links to more documentation. Or, Email Robert directly.

FHIR and the Ambulance: Notification of XDS documents

We had an interesting discussion today about how to ‘notify’ clinicians that there is a document in a repository for a patient that they are looking after.

The documents in question will be clinical summaries of ambulance visits, and will be held in a highly available repository hosted by the ambulance service, from which authorized users (including the patient) may view them. This repository will be part of an XDS style implementation, so the repository will create a metadata resource (DocumentReference) and send that to the Registry (which we’re terming a ‘Record Locator’ service).

Once there, clinicians and patients will be able to locate and view the documents in the ways that we’ve already discussed.

In addition to storing the document, we also want to be able to create a notification to the patients usual General Practitioner (Primary Care Provider to you US folk) so that they know that an ambulance visit has occurred and there is a new Transfer of Care document for them to review.

The reason for this is that it is very useful for the GP to know that their patient has been seen by the ambulance service, in case follow up is required. In many cases – particularly when the ambulance call does not involve a hospital visit – and hence there is no hospital discharge summary to the GP – they have no way of knowing that the visit occurred. An example of this is where the patient has an asthmatic attack and is nebulized successfully at home.

So the workflow will go something like this:

  1. The Ambulance system creates the document (likely a CDA) and saves it directly in its repository – along with all the other required metadata. (This is the integrated document source/repository actor in XDS).
  2. The Repository will generate a DocumentReference resource, and send that to the Registry.
  3. The Registry will save the DocumentReference resource, and also generate a new resource – the Notification resource – that is directed to the patients usual GP (which will be in the Patient.careProvider property). There’s nothing to stop it creating multiple notifications – eg to a patients care team – if there are business reasons for doing so.

Once this is done, GP’s will be able to receive the notification by means of an RSS feed querying the Notification resource like this:

GET [host]/Other?code='notification'&target=<GP>&_since=<lastQueryTime>

which will return a bundle (Atom feed) of Notification resources for that GP. They can then use the Notification (specifically the DocumentReference property) to retrieve the actual document for viewing.

So what is this Notification Resource? Well, it doesn’t actually exist yet. To implement notifications we need to use the Other resource, which has been specifically designed for situations like this: we need a resource that is not yet defined (or maybe won’t be). It has a simple structure:

  • Code – the type of resource. This will indicate that it is a notification resource.
  • Subject – the patient
  • Author – in this case the ambulance system
  • Created – the date of creation

And then you add as many other properties (as extensions) that you want. We’ll probably need:

  • Type – the type of Notification – eg that there is a new document for them. We could get fancier if we want to…
  • About – the DocumentReference reference
  • Target – a Provider resource reference to the GP

Why have we specified a separate resource for the notification, rather than just storing the GP as an extension to the DocumentReference resource and querying on that? Well:

  • A tight coupling in this way would mean that the ‘notification’ is for DocumentReference resources only, and we may want to support other Use Cases – such as a notification that a patient has been admitted into hospital.
  • More complex workflow – like the ability to record that the notification has been viewed and accepted (or declined) would be tricky. (Actually this is more Task type behaviour – but then, a Notification could be thought of as a type of task)
  • It feels like we’re binding together behaviour that doesn’t belong together.

Some other notes:

  • We’ll probably get the registry to provide a special service for this ‘save metadata and create notification’ functionality – eg POST /service/DocumentReference/saveAndNotify that takes the DocumentReference resource and does the rest. (I’ve grown rather fond of these services since Keith suggested them!)
  • Because the  notification query is based on an extension, the server needs to map the ‘target‘ query parameter to the target extension. We really want to be able to search on the identifier property of the Practitioner resource that is the target property of the Notification, so we’ll need to set up the profile accordingly.

And finally, in our particular situation there are a couple of wrinkles:

  • The delivery timeframe of the project is before the Record Locator service is likely to be in place
  • This design requires that the vendors of Practice Management Systems that the GP’s use need to implement the RSS/Atom query mechanism

For the first wrinkle, the RSS/Atom lookup will initially be provided directly by the Ambulance Repository application. Then, when the remainder of the infrastructure is in place the consumers will simply need to change URL’s to switch to the Record Locator/Registry and the system will otherwise work unchanged.

In the second case, there are a number of portal applications in use in New Zealand – we’ll add the display of notifications to those portals so that when GP’s and patients log into the Portals they will receive the notifications in the same way as they would from within their GP PMS. Hopefully, this will allow the PMS vendors to see the value of this approach, and implement the functionality directly (it’s not that hard for a consumer after all!)

Since writing this post, I’ve written another one, further extending the concept of Notifications, thinking about how to manage workflow.