Chris Royle: A-Z of FHIR Interoperability
By Chris Royle
Chris Royle shares A-Z of FHIR Interoperability:
I am passionate about healthcare interoperability and specifically FHIR – as I see it is the pathway to increasing data sharing and simplifying data access in this highly connected digital health world that we live in. We are seeing large varieties of patient provided IoT devices and network connected hospital devices. The growing set of data provided by these devices and the desire of care providers to gain access to this data to improve patient health outcomes, we need a standard’s driven approach – which FHIR provides. Integration in the form of point-to-point system communication is evolving to full Interoperability where data is available where and when it is needed across a connected eco-system and where, more vitally, that data is transformed to information.
Buckle in and dive in this collection of 26 posts that I created exploring FHIR – one for each letter of the alphabet.
A is for Audit Event
A is for AuditEvent. In the first in this series of A to Z of FHIR facts we look at the AuditEvent. This resource allows us to capture and share audit information about our applications in a standardised way. This can be used to inform others that a user has logged in or out of an application, or a user has searched for a patient’s record. It can also indicate whether the action was successful – based upon an outcome. The flexibility provided by this resource allows for very powerful sets of information to be shared about an action. It can include the actor who performed the action, their IP address, and can link to other FHIR resources that were affected by this particular action.
B is for Bundle
B is for Bundle. In the second in my A to Z series on FHIR facts it is important that I cover the Bundle resource. The FHIR web site explains that a bundle is a collection of resources that can have an independent existence. When you query resources from a FHIR server you will receive a bundle response back (except when you GET by id). This returns (hopefully) – a set of entry records matching the criteria you have passed in your query. When you are searching for matching entries the total field within the response will contain the total number of matches. Depending upon the number of matches you may need to work through a set of bundles to get all of the matched records. This is done through the link field which will have the URL for the next set of matching records.
But bundles don’t need to contain the same resource type. Each entry may contain a different resource type. If the bundle type is Message then the first entry will be a MessageHeader resource, and then other resources will follow it. You can also use Bundles with a type of Transaction or Batch to perform a number of operations on a set of related resources. This is a very powerful resource – beyond the searchset type. Explore Bundle to find out other ways of using this resource.
C is for CodeableConcepts
C is for CodeableConcepts. In the third installment of my A to Z on FHIR facts we are going to have a quick look at CodeableConcepts. They feature in most, if not all of the FHIR resources and is an important part of interoperating between systems. In simplistic terms it is a code and description of a code that describes a part of a resource – but it is much more than that. When a field has a type of CodeableConcept we are able to apply one or more different concept codes for the one field. This allows us to describe the data in ways that other systems may expect to use it. One system may provide SNOMED-CT AU terms which are described by the system – snomed.info/sct and the term itself. Other systems may use locally defined terms with a system URI which relates to the types of codes available. Although CodeableConcepts can include multiple codes in the one array, you can also provide a single code, and then leverage the power of ConceptMaps to map between them. Mapping through ConceptMaps allows mapping to be performed dynamically and allows for changes in mappings from one code to another. The system property within the CodeableConcept is important as it tells the recipient system what set of codes are appropriate for this CodeableConcept. The version property also can be important depending upon the system. As two codes may be different between two versions of the same coding system.
FHIR is all about increasing interoperability so remember it is important to describe our data as completely as possible so that it semantic meaning can be determined both by a system, and by a user – include the system, code, version and the display properties.
The CSIRO ontoserver provides a powerful engine for managing terminologies which underpins the Australian National Clinical Terminology Service, and is being implemented in the UK NHS as well as other international implementations.
D is for DocumentReference
Next in my A-Z series of fun FHIR facts is D for DocumentReference. As the name suggests this is a reference to a document. Documents can be scanned paper documents – like scanned consent forms, they can be images, CDA documents and other structured forms.
Document references can include the raw document data through the attachment data element or can simply be a URL link to where the document is stored.
The document type can be included referencing the LOINC code for various document types – for example, 59284-0 for Patient Consent. This allows queries against the FHIR server to find all of the consent documents for a given patient by looking for the type, and the patient id.
DocumentReference allows us to describe the document – so provides us the metadata about the document itself, and where it is.
Using the relatesTo element we can link this document to previous iterations of the document. So, in a clinical context where a Clinician appends other clinical content to a clinical document, we can see each iteration through the backward links to these versions.
We can also use the securityLabel element to drive how we relate to these documents – should it be restricted, or highly restricted. These labels then allow our applications, which are built on top of FHIR to add extra controls to either limit access or request additional authentication prior to access.
E is for Encounter
Next in my A-Z series of fun FHIR facts is E for Encounter.
Encounters are simple enough to think of in a healthcare context – an inpatient visit, and outpatient attendance, an emergency visit, but it can get complex depending upon how we think of an encounter – when it starts, when it has finished.
The partOf element allows us to build a list of encounters based upon relationships. An inpatient encounter may have various sub-encounters.
The simplest way of thinking of the encounter is an inpatient visit which includes some transfers to various locations around a hospital – shown by the location element with specified periods.
Carefully consider the status of the encounter – as it may be a planned encounter (not yet actual), or could be in-progress, or even cancelled.
The definition of the Encounter resource shows participants and locations as separate elements meaning that to understand who a particular treating doctor is at a given location, we need to look at the period of both elements to determine this.
The standard calls out the differences between it and the Appointment resource in an outpatient context – so just be careful with that aspect. I think of the encounter as something that is actualised, whereas Appointment is the plan about something to occur.
F is for FHIRPath
Next on our journey from A to Z on FHIR facts we are looking at FHIRPath.
FHIRPath is used in a variety of areas throughout the standard. It can be thought of similarly to XPath and describes a particular part of a FHIR resource or operations on a FHIR resource.
FHIRPath can be used for path selection, as well as extraction. An example of selection is when we search for records from a FHIR server. You can query based upon a record within the FHIR construct – for example participant.type when querying the Encounter resource. You can also use FHIRPath when performing a Patch operation. This allows you to add, remove or replace parts of a FHIR resource – all described using FHIRPath.
FHIRPath also supports operators and functions allowing it to be very powerful. The standard illustrates this particular example.
Patient.telecom.where(use = ‘official’).union(Patient.contact.telecom.where(use = ‘official’)).exists().not()
FHIRPath is being used as a part of the CDS Hooks standard, TestScript resource and other parts of the standard as well. This is well worth getting your mind across this part of the standard. It is published outside of FHIR as it is applicable more broadly.
G is for ImplementationGuide
G is for Implementation Guide. OK – it is more I than G – but it is an important part of our journey in the A to Z on FHIR facts.
FHIR is all about providing a base set of elements that the majority (80%) of implementers need to support healthcare data sharing. The implementation guides are used to define how a particular set of resources are used including extensions, terminology sets, and profiles for use. An example of an implementation guide is the AU Base – which describes how implementers believe the FHIR resources should be used in an Australian context. This covers key Australian contexts like the Individual Healthcare Identifier, Medicare Number, and Australian Indigenous Status.
These implementation guides encourage reuse and enhanced interoperability through define national, and regional best practice.
Implementation Guides can also be computable by defining them within the ImplementationGuide resource.
H is for Hooks
Today’s topic on my A to Z of fun facts on FHIR we are going to look at H for hooks – CDS Hooks.
CDS Hooks works alongside the FHIR specification and describes the RESTful APIs for interacting with a clinical decision support system.
Hooks represent an action that a user is performing – like ordering a test, prescribing a medication, or even discharging a patient. A hook has a context which might be a user and a patient. This allows us to understand the parameters that the hook needs to know to understand what to do. The request for a hook also allows a prefetch template to be defined. This allows for a read or search of the FHIR server to be performed based upon some information provided to the interaction.
When a CDS hook is interacted with it returns an array of cards. Cards describe the interaction with the clinical decision support service. They can be used to provide suggestions to the user. These suggestions may be suggesting alternate medications to be ordered based upon decisions that are made by the service. The user can then interact with the CDS service (through the hook) to change the prescribed medication or perform other appropriate actions – based upon the possible outcomes.
Although it is named CDS hooks it can be used for other non-clinical interactions, and the standard gives a patient view example.
I for ID and Identifiers
I for Ids and Identifiers. In this episode of A to Z on FHIR facts I wanted to look at the differences between ids and identifiers within a resource.
Each resource has an id – which is a logical id for the record. It is assigned by the server hosting the FHIR resource. The id is unique for a given record and is never changed. On the other hand – an identifier against a record can be changed. Identifers are business identifiers for a given resource. If we think of a patient, they will have a number of business identifiers such as patient medical record number, Medicare number. These numbers may change, they may also be valid for a period of time. A logical identifier for our patient resource is how we reference and refer to it. It is also how we read it from the FHIR server. If we reference Patient/123 we are asking for the patient with a logical id of 123 to be read from the FHIR server. Business identifiers have system URIs which define the type of identifier. This will indicate to a consuming client system that this identifier is a medical record number, or a Medicare number or some other identifier type. FHIR servers can assign logical ids using a variety of methods – some simply increment an auto number, others may user GUIDs or other ways of obtaining uniqueness.
FHIR supports the assigning of a logical id when you create a FHIR resource through the use of the PUT verb. If a client application performs a PUT and the resource doesn’t already exist, then it can create a resource with that specified resource id. Note that not all FHIR servers support this capability as it is a design decision.
J is for JSON
We are up to J in our A to Z journey through FHIR and I thought it would be important to have a quick look a JSON. In FHIR we have a couple of formats for how we interact with a FHIR server and deal with FHIR resources. We can use XML, or JSON. We can provide a Content-Type header to define which format we want to use or receive back. For xml – application/fhir+xml or application/fhir+json for json data structures. There is also another format called turtle, but it is less frequently used.
I prefer JSON because the data structures are smaller (typically) than their XML counterparts, and I find it easier to read and navigate programmatically. There are pros and cons to each format.
One important note for working with JSON is making sure that we take care with numeric precision. The following link to the FHIR specification calls this out and suggests a custom parser. Thanks Angus Millar for reminding me of this one at the Sydney HL7 Connectathon in 2020. A quick call out – attend a Connectathon when you can – they are great places to learn in a safe place with some great people.
Regardless of the choice you can interact with the FHIR server using this format and have the same set of operations and capabilities.
Thanks Grahame Grieve, and the broader FHIR community for making sure that we have the options when interacting in a FHIR construct. It increases the level of interoperability through lowering the barrier to adoption.
K is for Knowledge Base
Today we look at the letter K – for Knowledge Bases. In this quick post of A to Z of FHIR facts I wanted to point to the large collection of resources on FHIR. I am certainly not the font of all knowledge on FHIR – not even close. There are so many resources available on FHIR – from the specification itself including examples, forums, blog posts, and other content all publicly available. One of the many things I love about FHIR is the openness. Openness of the Standard – through a comprehensive website, and openness of the community within FHIR. As a community – we want to improve healthcare through better data access, and better sharing of data.
Let’s start with the FHIR standard itself. Here we can see detailed explanations of each of the elements of each resources, examples in XML and JSON, best practice guides, mappings to other standards like HL7 v2 and v3, and a wealth of other knowledge compiled into an easy-to-use web site (and searchable too). I think I visit the site at least a couple of times a day.
Got a specific problem with the FHIR standard in something you are implementing? You will likely find that you are not the only one thinking about that problem. There is an active, collaborative community ready to help available on how to work with FHIR in the real-world. Ask your question to the community – you will find they are quick to respond, and no question is a stupid question.
As mentioned on my last post HL7 Connectathons are a great way of learning – learning through experience. There is nothing like learning from those who work with FHIR every day and know the nuances of the Standard.
L is for List
L is for List. In this episode on A to Z of FHIR facts I wanted to explore the List resource and how it can be used.
FHIR outlines that a list is a curated collection of resources. Normally when we query a resource endpoint we receive back a bundle of resource records matching a particular query. This might be a list of patients with a certain name, date of birth and sex. We then receive a bundle of these patients based upon that criteria.
Sometimes we might want to keep a track of patients that we are interested in. These might be patients that are current inpatients assigned to my speciality, or it could be a set of patients who are involved in a particular clinical trial, or it could just be the last 10 patients records I have accessed. One way of managing these lists of records is by using the List resource.
The list has a mode which tells you how the list has been set. It can be a snapshot (point in time), it can be a working list which is maintained with updates and can also be a changes list which shows the changes that have been made over time. Like a bundle the list has a collection of entries which reference an underlying resource – like a patient, practitioner, etc.
Considering the snapshot mode – we can think of examples like a discharge medication list for a patient. This is a point in time view of the patient’s medications based upon a specific discharge – it won’t necessarily be the same as the patient’s current medications.
Items within the list can also be ordered so we might want to see certain entries first, followed by the rest.
Lists can contain the same resource items – e.g. Patients or it can contain different FHIR resource items like Conditions, AllergyIntollerances and Procedures (for a problem list).
M is for Maturity
M is for Maturity. In this part of my series on A to Z of FHIR facts I wanted to have a quick look at the maturity level of FHIR resources and what it means. The evolving nature of FHIR means that some resources are more mature than others. There are 7 maturity levels within the FHIR Maturity Model (or FMM). Each release of FHIR comes with resources of varying levels of maturity.
The lower the maturity level, the less the resource has been used in production implementations and more subject to change it is.
The levels are cumulative – each level has the features of the level below it.
Here is a summary of the levels: –
Draft (0) – this resource has been drafted in this particular FHIR release.
FMM 1 – the responsible working group considers the resource substantially complete and ready for implementation
FMM 2 – it has been implemented in at least 3 different systems
FMM 3 – it has subjected to formal balloting
FMM 4 – has been formally published and implemented in multiple prototype projects
FMM 5 – has been published in two formal publications releases and implemented in at least 5 production systems in more than one country
Normative – considered stable
The more mature the resource, the more stable it becomes.
You can use the Maturity Level to determine when to adopt a particular resource, and when to wait. It shouldn’t stop you adopting a particular resource, but you need to take it into consideration. If a resource is draft, then it will likely change considerably over its progression and you may need to change your code as well. Don’t be scared of using a lower maturity level resource – these need to be implemented in the real-world to test and see how they fulfil the goals of FHIR in real life.
N is for Normative
Following on from yesterday’s discussion on Maturity, today in our path from A to Z in FHIR we look at a related topic – N for Normative.
The Standard has a great section of the main site discussing the Standards development process and how the Standard evolves. “standards need to evolve. At the same time, the evolution of standards needs to be predictable and manageable for the implementation community” it says. The evolution of the Standard itself through draft, trial use to normative allows the Standard to change, but in a predictable way. Balloting of the Standard progresses it through a number of stages.
When you look at the v4.0.1 version of the FHIR specification you see that the status is R4 – Mixed Normative and STU. This shows the evolving nature of FHIR. We have a set of resources with a mix of maturities some being drafted, some ready for trial use and others normative.
When the resources themselves reach normative we have some certainty – some predictability. They are then considered to be ‘locked’. This doesn’t mean that the resource can’t change – it means that they are subjected to the FHRI Inter-version Compatibility Rules. These rules give implementers the predictability that they need. These rules offer both backward and forward compatibility of resources which are changed once in the normative state.
O is for Operations
Today on our journey from A to Z on FHIR we look at O for Operations. This part of the Standard I found one day when looking at the CSIRO Ontoserver and the way it performs code lookups and mappings. Against the CodeSystem resource I can perform a $lookup operation and pass in the parameters for my lookup. The FHIR server behind the scenes will lookup the record based upon its repository and return the matching data. When I first found this part of the Standard – and no – it wasn’t hidden – Operations can be found in the main header within the FHIR web site. Hidden in plain sight. When I did find this part of the Standard – I had to see what other operations existed and why I might need to use them.
There is quite an extensive list of operations on the FHIR site – including $expand for ValueSet which allows you to expand out a list of values within a ValueSet using filtering. The one I like is $everything on the Patient resource. This operation (if supported) will return all information related to one or more patients. It returns a bundle containing these details. Imagine the use cases for this operation. There is also a $match operation for enterprise master patient index functions against the Patient resource.
The Standard also allows you to define your own operations – which can be done through the OperationDefinition resource. This shows us some of the power of FHIR as a standard – extensibility.
Discover FHIR operations – start with terminology operations like $lookup or $expand and see where you get to.
P is for Profiles
P is for FHIR Profiles. In this part of our journey from A to Z on FHIR facts we look at Profiles. Profiles are an important part of the standard in the way that pull together the various building blocks provided by the standard for a specific use case. Profiles are constraints on core FHIR resources and data types for a given use case, or a region. If we look at the AU Base 2 profiles we have a definition on how resources should look in an Australian context. Other similar profiles exist in other regions and other implementations. A profile can be based upon another profile or simply the base resource. As an example, if we look at the AU Base 2 profile for the Patient resource we can see standardised extensions allowing implementers to share common Australian data flows without needing to define new extension for these common data elements. It also defines additional constraints on these resources. The profile shows that you can have an Individual Healthcare Identifier (or IHI) within the list of identifiers which includes extensions for identifier status and record status as per the Australian standards.
The base standard allows for Codeable Concepts to be linked to different systems depending upon the element. A variety of different systems can be used for a single element. A profile can constrain these to a single system which allows for standardization in a given use case.
Like everything in the FHIR standard, profiles can be defined programmatically through the StructureDefinition resource.
Working on a FHIR project – check to see if there is a profile that relates to the use case so that you don’t have to reinvent the wheel. This reusability points to the “FAST” part of the acronym FHIR. Reuse instead of re-invent.
Q is for Questionnaires
Today in our path from A to Z on FHIR facts we look at Questionnaires, and specifically the QuestionnaireResponse resource. There are a lot of forms that we complete in healthcare. There are pre-admission forms, family history, claim forms, research forms. In the past this would have been a large collection of paper that was sent to you prior to admission, but more and more this information is becoming electronic. The QuestionnaireResponse resource captures the responses to a specific set of questions. This set of responses can be related to a Questionnaire. Think of the Questionnaire resource as the list of questions that you want to ask, or the structure of the form itself. QuestionnaireResponse is then the set of answers given by the recipient. You don’t need to have a questionnaire to respond to it, but you can.
When I look at the QuestionnaireResponse resource I think about all of the generic form builder applications I have used in the past. It can be a flat structure with a set of questions, or it can be grouped into sections, with each section containing a set of questions, or more groups. The answers that are given by the recipient will have a specific type – Booleans, strings, integers, codes, quantities, etc. If you have created a Questionnaire resource, you can define the data types for each of the questions and associated possible responses.
Questionnaires are a great way of creating the myriad of forms that we use in healthcare and allow the sharing of this data to other systems. As they have a generic structure it is important that we think about interoperability. Ask yourself the question – should I be using another FHIR resource to represent this data instead of a QuestionnaireResponse resource? Think about an example of providing a questionnaire to a patient about the medication they are on. We could ask them a set of questions and communicate this as a QuestionnaireResponse, or we could use the MedicationStatement resource. By using the MedicationStatement resource we are providing better interoperability between systems as we know the purpose of this Medication Statement information in a clinical system – we can start to use it for decision support.
R is for References
R is for References. In this post on A to Z on FHIR facts I wanted to explore references. References are the way we link resources together. If we consider the FHIR Encounter resource it will contain links to the patient that this encounter is for, the practitioner who is a participant in this encounter and links to locations and organisations where the encounter may take place.
References are linked based upon their identity – eg. Patient/123.
References can be an absolute or relative URL. A relative URL is relative to a given FHIR base endpoint. References can also be related to a contained resource. This allows you to pass in the content of another resource without having to specify it separately. These contained resources are identified by a hash character (#).
Think about the display element of the reference. This provides a way of giving the receiving system information about the referenced resource without having to retrieve it. For a patient – this might be the patient’s name, or their medical record number. Remember though – if you are storing the reference information in encounter resource (or any resource) and that information changes it should be modified in the encounter resource too. Imagine in the above example that the patient’s name changes – we may want to change the name of the encounter resource, but we may not want to. It might be important to know what the name of the patient was during that encounter?
S is for Subscriptions
S is for Subscriptions. In this post on A to Z on FHIR facts I wanted to lift the covers on subscriptions. I think this is the one I have been looking forward to the most in this series. Subscriptions is such a powerful part of the Standard and I think a little overlooked.
In the Subscription resource we can define push-based subscriptions from a server to another system. This is where we can ask a FHIR server to send us notifications when a certain criterion has been met. There are so many uses for this publisher / subscriber pattern. In some simple examples, as a client application I want to know when a new code has been added to a ValueSet so that I can refresh a local cache. I might want to see when a patient record has been added. There are many other examples that we could consider.
When a criterion has been met, data can be sent by the FHIR Server to a REST hook, a web socket, an email, sms or a FHIR message (Bundle with a MessageHeader). This provides a method for knowing when something has happened by receiving an event instead of constant polling of a FHIR server.
The way that a FHIR server may implement the subscription depends on the capabilities of the FHIR server implementation. Some servers may poll their data stores, others may use database triggers, or more modern event models.
Check if your FHIR server supports the subscription resource and think about the patterns you are using to see if subscription is a better approach – than constantly polling the FHIR server. Please don’t poll the FHIR server – just because you can, doesn’t mean you should.
The other quick mention for S is SMART on FHIR. SMART is a universal API to transform EHRs into platforms for substitutable apps. SMART on FHIR started in a United States as a way of providing a common base interoperability for app development across the set of EHRs used in the US. The lofty goal of SMART on FHIR is for an innovative app developer to be able to write an app once and expect that it will run anywhere in the healthcare system and that it can be substituted for another app (if needed). SMART on FHIR provides the profiles for use (as we have discussed previously in this series). An important part covered by SMART on FHIR is the use of Open ID Connect and OAuth 2.0 in how applications should authenticate and authorize access.
T is for Task
In today’s post we are going to look at T for Task in my series of A to Z on FHIR facts. I was going to talk about terminology – but feel I have touched on that previously. Terminology is really important so if you want to know a little more – have a look at my post – C for CodeableConcepts and check out Terminologies on the FHIR web site.
The Task resource is a part of the workflow group of resources within the standard. It is used to keep a track of activities that run through a set of states. Think of monitoring a state machine. A task resource goes through a set of states through to a finalised state – such as completed. The standard outlines that a task spans both the intent and the event. Think about a task which is a request for an orderly to move a patient from the Emergency department to a ward. We have a planned task which is requested by a Clinician to move the patient – which is a task, then that event goes through the various states of being completed. An orderly accepts the task, and it transitions from a planned activity, to an event which will be performed. The orderly picks up the patient from emergency and delivers them to the ward. The task goes through the states of in-progress (making sure that another orderly doesn’t go to pick up the same patient) and progresses through to completed.
Tasks can be much more than an orderly request, they can include signing an order, acknowledging a result. The standard also discusses how the workflow action of a task often runs in parallel with clinical resources. This means that there may be another clinical resource that relates to this workflow activity – like a ServiceRequest, or a DiagnosticReport.
U is for Usability
In our journey from A to Z on FHIR facts we have reached U. When I think about FHIR – I think U for usability. In the past I have tried to explain to people outside of healthcare about HL7. Prior to FHIR, this conversation would go. “Think about going to the hospital. You might go to Emergency and the hospital arrives you in, records some demographic information and then record all of the places you go around emergency and your discharge from ED, or admission to the hospital. They might order tests or get you to go get an X-ray. The various systems around the hospital need to know who you are and where you are, which doctor needs to know about your results when they come back.”. OK, for anyone in healthcare – apologies for the oversimplification. I try and explain hospitals a bit like a hotel visit – it can be easy for people to get sometimes. The responses I use to get would range from – “that seems crazy”, “that seems like the 1970s” to – “does it really work that way – surely there is a better way”. All quite valid responses. When we look at the initial HL7 v2 specification it is that old. It did well in communicating information from one part of a hospital to another part – from the ED clerk to the pathology department (for an order), from pathology back to ED (with the results).
This point-to-point messaging was replaced with integration engines and enterprise service bus components to perform hub and spoke patterns to simplify the chaos, but it was still point-to-point.
I speak to mobile app developers who want to write healthcare applications, and prior to FHIR they would say – can you provide a web service for me to call to get patient information or give me access to the database so that I can get the patient details. Try explaining to a mobile app developer in 2021 that they need to understand the various segments of an A28 or A31 message and count the pipes and carets. After a few moments you will see the look of fear on their face. Feel free to laugh at this point. The grand idea that they had for their mobile app suddenly fades away as they think through all of the pain, they need to go through to get this simple data that they need.
All of this leads to higher levels of usability and increased data access. Unleash the creativity of clinicians in a controlled and governed way through FHIR.
V is for Versioning
Today in our journey from A to Z on FHIR facts we look at V for resource versioning. Every time I update a resource a FHIR server can update the version of the resource, held within the resource metadata section (meta). If a server supports versioning, then you can ask for specific versions of a resource when you perform a GET operation. This can be useful to see how a record has changed over time. When you perform an update, you want to make sure that the record you are updating is based upon the information you have already, and has not been changed since – but more on that tomorrow.
The vread operation is a read (or GET) of a particular version of the record.
You can also retrieve all of the history of a particular FHIR resource by looking at the _history of the resource id.
The version of the resource is shown in the meta element of the resource and can be seen in the ETag header when getting a record.
Create, update and delete interactions create new versions of our resources, but other interactions won’t. If we GET a resource, it does not update the version – which makes sense. Depending upon the FHIR implementation, a GET operation may create other resources like AuditEvent to keep a track of what user interactions are taking place.
Versions don’t need to be sequential numbers – they are just identifiers for a unique version of a record. FHIR servers can use GUIDs for versions making them globally unique, or they could simply be an auto number starting at 1. A client consuming the FHIR server cannot assume that because I have version 22 of the resource that it is 2 changes past version 20 – that would depend upon the implementation. There is nothing in the standard about these versions being sequential, or even numeric.
Note that not all FHIR servers support versioning. A good way of checking is performing a read on a FHIR resource and checking meta.version element. If it is not present – then no versioning is supported by the FHIR server. It is also mentioned in the FHIR capability statement.
W is for WWW verbs
We are getting close to end of this series of A to Z of fun FHIR facts. Today we look at W for WWW verbs. When we interact with a FHIR server we use these HTTP verbs to drive what happens to the resources. Typically, we GET and POST, but we can also PUT, PATCH and DELETE as well.
When we PUT a resource, we are asking the FHIR server to substitute the existing resource with the one we are putting. We pass in the ID of the record that we wish to update. When you are performing a PUT operation it is important that we are updating the record we believe exists on the FHIR server. In other words – let’s say that we perform a GET to retrieve our patient record. We then want to update the patient’s address. If someone else has subsequently updated that patient’s record to update another part of the record – like the date of birth, then the record that you have just retrieved will be different from the record that now exists in the FHIR server. In the header of the GET response you should have received an ETag header. This will contain the version of the resource that you have retrieved. When you PUT the resource back you can pass an “If-Match” header record with the same version. If the version doesn’t match, then the FHIR server will respond with an error status to stop you from losing updates.
You can also create a new record by using PUT and passing in your own id. This can be useful if you are maintaining an id from another system. This functionality – PUT as create is not supported by all FHIR servers so you need to check with the capabilities of the server you are communicating with.
PATCH is simple to think about but a little more difficult to work with. With patch we are asking the FHIR server to modify part of an existing resource, instead of wholly replacing the existing resource. I must admit – I prefer to do a GET and PUT combination instead of using PATCH. Patch can use JSON Patch, XML Patch and even FHIRPath Patch format patching to update part of the resource. You can use the ETag versioning check with a patch as well to ensure that you are updating the record you think you are.
DELETE is straight forward – it does what it says on the tin. When a FHIR server maintains the versions of each of the FHIR resources you will still have previously created versions when you perform a DELETE operation.
Another thing to keep a note of is the HTTP return status codes for each operation. This tells you a lot of information about what has just happened from your operation. When you perform a DELETE you will receive a 200 status if the entry exists and has now been removed, or 405 if you are not allowed to delete that particular resource. You cannot just assume that your action has been performed without checking on the status codes.
X is for eXtensions
X is for eXtensions. I couldn’t help putting this one in. What would FHIR be without extensions. In this episode on A to Z on FHIR facts I wanted to explore how extensions can be used, and you should think about when using extensions.
In HL7 v2.x we had extensions which allowed us to define the information that didn’t have a home in the standard, but that we needed to share between systems. It was great to be able to solve a particular problem with a communication between two systems, but it was always a discussion between two vendors – “what information do you expect there, and what is it used for”. As I say this flexibility was great, but it was always just a conversation and hopefully a specification on what it was used for and why. In FHIR extensions are a key part of the standard and allows us a mechanism for answering the “what it does” and “why” questions. When you define an extension, you provide a URL to where the definition of that extension lives. This allows other vendors using your FHIR resource to understand what the format of the data is, why it is used and what is the expectation for it is. Each extension is comprised of a URL and a value. The value can be of any type within FHIR, and the URL then points to the definition. Extensions can be used for targeted projects, particular speciality projects and even for country-wide usage.
There are extension registries where there are common extensions defined. This is an important part of extensions. We want to reuse where available extensions that exist, rather than recreate another. In the Australian Base Implementation Guide (or IG) there are a collection of Australian base extensions which apply to the base FHIR resources. These are a collection of extensions that are typical in the Australian market. Other jurisdictions have their own set of extensions. Even within the Australian market there will be extensions specific to NSW, or Victoria, as required by projects there. In Australia (as an example), IHI Record Status and IHI Status are important extensions for tracking this key national identity information for our patients.
When you can’t find an element within the FHIR standard that you need to communicate with others – check the various FHIR registries to see if someone has already created one, check with the FHIR community too – there may already be another way of communicating it. If all else fails – create your extension – this is what it is there for. Overtime, the extension may get folded into the standard and then you can work on the migration to the base resource, but until then you are able to interoperate with others.
Y is for Security and Privacy
Y is for Security and Privacy. OK, I’m pushing the letters here, but I couldn’t leave out this important aspect of FHIR.
If you search for security on the FHIR site you will be told that “FHIR is not a security protocol, nor does it define any security related functionality”. It then continues by saying that it defines exchange protocols and content and should be used alongside existing security protocols defined elsewhere. I think this is really important. Security protocols and standards already exist in the world – so why create them again. Depending upon the aspect of security you are looking at, the standard and protocol will be different.
For communication security we can think about SSL and TLS – which includes any API management components. We can think about digital signatures and signing documents that are created within FHIR. We can think about audit – with the use of the AuditEvent resource – tracking who and what has been accessed or modified. We can also think about authentication using standards such as OAuth – where SMART on FHIR comes into play. We can also think about authorisation as to who should have access to what aspects of our data and when. This can be covered by existing IHE profile recommendations.
From a privacy point of view – we can utilise the security labels capability within FHIR to inform others how to treat the data which has been received from the FHIR server. This allows the capturing and communication of confidentiality information from a data sensitivity perspective. It also helps us think about how to share information about “break-the-glass” patterns for accessing records in certain use cases.
When I think about privacy – I also think about consent. Now way back at the start of this journey I could have covered C for consent, but alas I didn’t. I definitely recommend consulting the consent resource within the standard for understanding how to share this consent information between applications. Consent is more than just consent to share information, it covers treatment consent, consent to share information for secondary use.
Sharing information is key to FHIR, but we need to do so in a secure manner.
Z is for Z messages
I’m a bit sad that we have finished our journey from A to Z. I have really enjoyed putting this series together, and I hope that you have learnt something along the way. I also hope that I have inspired you to find out more about FHIR so that together we can improve healthcare through better data access, data sharing and interoperability.
Today Z is for Z messages, Z segments, but in FHIR – Z is for Basic. The Basic resource allows us to describe a resource which is not currently part of the standard. Why do we need such a component? The Basic resource allows us to describe that currently hasn’t been added to the standard yet. There may be a reason to add it in the future, but at the moment it doesn’t exist. Because the aim of FHIR is to improve healthcare interoperability it is important that we carefully consider the use of the Basic resource. The standard suggests checking on the Stack Overflow pages for similar use cases to see which method other implementations are taking to solve the same problem. See the Best Practice section of the standard to check through all of the things you should do. At some stage in later releases of FHIR your resource may become part of the standard, so you need to consider this as a part of the transition back to the standard.
Extensibility is an important part of FHIR – as we saw in the Extensions post, and the Basic resource is yet another example of the Standard’s extensibility.
Do you have a current use case where no other resource will fulfil the requirements, and you are having to use the Basic resource – consider being an active member of the standard community and maybe you can get your resource added to the standard – maybe it is reusable in more than just your environment.
It has been my pleasure writing these posts taking you through FHIR from my perspective. I encourage you to learn more about the standard – make Fridays your FHIR days and learn something new about the standard.
Understanding FHIR and how it can be used in improving healthcare interoperability is a key first step and so too is using a platform which is inherently FHIR-based to enable use cases for information access – not just sharing data between two systems.
Contact me if you’re interested in learning more about the Dedalus Digital Connect 4 Health (DC4H) Platform in how it can leverage the HL7 FHIR standard to innovate at the edge of your existing system landscape, or even if you have a use case that you wish to explore using FHIR.
Follow Chris & Dedalus on LinkedIn for more great Healthcare insights and perspectives!
Get in touch now & email: firstname.lastname@example.org