4 min read

FHIR Subscriptions and state changes

HL7 FHIR (Fast Healthcare Interoperability Resources) is an open standard for healthcare interoperability. Microsoft contributes enthusiastically to FHIR and the health standards community, from developing open source servers, tools, and libraries to hosting managed services in Azure, as well as technical evangelism and development of core specifications.

From time to time on this blog, our team will share thoughts, design challenges, and implementation progress with the community for transparency and feedback. Today’s post is the first installment, which focuses on upcoming changes to FHIR Subscriptions.

As FHIR adoption grows, the community begins to tackle more complex workflows. Critical in many of these workflows is the ability to send notifications to clients based on actions happening within a server. One mechanism for managing event notifications to clients is FHIR’s built-in Subscription resource. In the upcoming FHIR release (R5), there is a significant redesign of the Subscription resource and the notifications mechanisms around it.

The redesign introduces the ability for servers to send notifications that include either references (by resource ID) or the full contents of resources involved in an event. As the new design has matured, we’ve had in-depth community discussions about what should be included in notifications and below is a summary of the results.

As context, at its core, a Subscription generates notifications about state changes. A state change implies two views of the world: the state prior to the change, which I’ll refer to as the ‘previous’ state, and the state after the change, which I’ll refer to as the ‘current’ state. When considering a RESTful server (e.g., a FHIR server), state changes can be sorted into three buckets: create, delete, and update (the CUD in CRUD – since reads don’t change state).

  • Create operations are the most straightforward – there is only one useful state because the previous state was non-existence. An implementer is safe to assume any information refers to the current state and any notification structures can be filled out at the server’s leisure. Trying to include data from the previous state just doesn’t make sense. With that in mind, the ‘best’ offering from a server is to include data (ID, resource, or graph) based on the current state of the world.
  • Delete operations feel like create at first – the previous state is the only valid one, so any data would need to be pulled from it. Unfortunately, it isn’t that simple. For example, if a resource was deleted for privacy reasons, a server shouldn’t broadcast it. Additionally, sending a resource after it’s been deleted isn’t consistent with what a client sees when querying a server. On the other hand, a client trying to discover which resource was deleted (e.g., determine a missing patient from the server) is an expensive operation and should be avoided. Given all these concerns, I consider the ‘best’ behavior for a server to include the ID of a deleted resource, but no actual contents.
  • Update operations are the most complicated – both the previous and current states are generally valid, and both are potentially useful (e.g., a client can easily determine the specifics of an update). Here, there are three main areas to consider. First, there can be privacy, security, or safety issues similar to delete operations – invalid states shouldn’t be broadcast. Second, if a client needs to do comparisons, it can cache data in a local store or issue versioned FHIR resource requests as a follow-up. Finally, requiring servers to pull resources or graphs from the previous state has significant performance and design implications – notifications can’t be processed out of band since they need data from both states around the update. All considered, I believe the ‘best’ offering from a server during an update is to pull IDs, resources, or graphs from the current state of the system; anyone who needs a previous state should be taking care of that on their own (e.g., by issuing history or versioned read API calls).

There is one more issue that I’d like to cover, which is the possibility of missing intermediate states. There are several scenarios where this is possible: high frequency updates to a resource, server processing queue backup, transmission times to clients, etc. If knowing all intermediate states is important to your workflow, the implementation server must support versioned links on all resources of interest and provide guaranteed delivery – both of which are beyond the scope of FHIR Subscriptions.

By using versioned resource links, each update in a server will be unique, and clients can retrieve those exact versions at their leisure. By supporting guaranteed delivery, a server can ensure that a client hasn’t missed any states due to transmission. Given that these are not the expected behaviors of generic servers, workflows should expect that the only knowable state of the server is the ‘current’ state. To use the official language: “Here Be Dragons!” – take care in your design.

We’re targeting the May 2020 ballot cycle for the Subscription redesign, and we’re eager for your early feedback. The draft specifications are hosted on the FHIR CI Server and our testing infrastructure is hosted on Azure. The best place to reach us is the Subscriptions Stream on the official FHIR Chat Server and we’re hosting a Subscriptions track at the CMS Connectathon #1 (January 7-8 in Baltimore, Maryland, US) and supporting the Subscriptions track at HL7 FHIR Connectathon #23 (February 2-3 in Sydney, Australia). We hope to hear from many of you in the coming weeks and look forward to seeing you at these events.

Other feedback or questions? Let us know in the comments below.

FHIR® is the registered trademark of HL7 and is used with the permission of HL7.