FHIR Forms: Theory and background

In this set of posts we’re going to dig into how FHIR supports the use of forms in collecting information. 

We’ll start with the theory – how the Questionnaire and QuestionnaireResponse resources work together to define a form and record the information entered into the form (whether directly by the user or pre populated from existing data)  and then describe an example implementation that we’ve built in clinFHIR. 

Forms are ubiquitous in healthcare (and other domains for that matter) so it makes sense that there is some specific support in FHIR for them.

There are 2 key resources that are the backbone of forms support in FHIR – the Questionnaire and the QuestionnaireResponse resources (for simplicity we’ll sometimes refer to these as ‘Q’ and ‘QR’ in the discussion below)

The Questionnaire (Q) Is the definition of a form. It has a header section that describes what the form is about, identifiers, who created it, when it should be used and similar information The contents are in item elements, that can be nested to any required level. This makes the tree display a good way to view the items, as we’ll see when we discuss the clinFHIR forms module.

The QuestionnaireResponse (QR) is the contents of a single form instance – a completed form. It is generally associated with a Questionnaire (though can act alone – kind of like a Value Object). The association uses a canonical url rather than a resource reference. It also has a header with elements like the patient, who completed the form, the date and so forth. And it has a contents section (items) that mirror the structure of the Questionnaire – ie the tree representation of the QuestionnaireResponse contents is the same as the matching Questionnaire. 

So both Questionnaire and QuestionnaireResponse have the contents represented as items, and each has a unique linkId element which links the two. Thus the linkId of the item in the QR links to the corresponding (definitional) item in the Questionnaire.

But where the item from the Questionnaire has the definition of the question, the corresponding item in the QuestionnaireResponse has the answer. Simple really.

One thing you may notice when you look at the Questionnaire in the spec, is that there isn’t much on the item element that refers to the desired form layout. There’s quite a bit on behaviour (when to display, how many allowed in a form  and pre-population details for example) but not a lot on format. This is intentional, in order to keep the base resource (relatively) simple. However, the specification does include a large number of extensions that can be used by implementers for specific purposes.

So we’ve described how the Questionnaire/QuestionnaireResponse (Q/QR) combo can define a form and collect the information in a structured way. But, often this won’t be enough: we want to have some of the information entered in the form to be saved as separate resources. For example, suppose our form is completed by the patient and had the question “What is your current weight”. It’s great that we can look at the form any time and see the value they entered, but it would be greater if that was represented in the FHIR server as an Observation resource. Then, we can query for Observations with the code for weight (from the Vital Signs IG)  through the API without going through the form. 

It’s time to introduce the Structured Data Capture (SDC) implementation Guide.

This guide, which has been developed over a number of years and connectathons, takes the Q/QR combo and describes how to use them in typical scenarios. It adds further extensions to the mix, and talks a lot about advanced forms technology – such as rendering options or  adaptive forms that can reorganize themselves dynamically.

And, specifically, it talks about how to extract separate resources from a QuestionnaireResponse instance.

The mechanism for doing this is described in SDC as part of the Forms Receiver role. In essence it describes specific ways that the Questionnaire can be structured so that the forms receiver is able to create these resources from the information in the completed QR. There are actually 3 different methods described in SDC. (For detail, see the SDC extract page)

Observation extraction is the simplest – and likely the most commonly used. All that is needed is to place the Observation code in the item.code element of the Questionnaire and the value in the corresponding item.answer element of the QuestionnaireResponse, and the Observation can be created using those elements, and some from the header of the QuestionnaireResponse (patient, form filler, date of observation etc). To ‘instruct’ the receiver to perform the extraction, a specific extension is added to the item. Quite often, you’ll also want to add a units extension as well.

Definition based is the next option. Also triggered by an extension which identifies the type of resource to be created, the idea is that there is a ‘parent’ item (with the extension) in the Questionnaire that has child items containing the values of specific elements to be copied to the extracted resource. The child items use the item.definition to specify which child item has the value for which extracted resource element. It’s possible to include hidden items that the user doesn’t need to see or complete – like a ‘status’ element for example.

As with the Observation approach, the Questionnaire contains all the definitional aspects of the extraction, while the QuestionnaireResponse has the actual data for a given form instance.

StructureMap is based on the FHIR Mapping language to perform the extraction. It is the most versatile – though most complex – approach. It’s likely that the other 2 approaches will serve the majority of needs, but there are likely to be circumstances where it is needed – especially if the Questionnaire was not designed with resource extraction in mind.

You may think that this is all a bit complicated – why not just have the form filler create the bundle of resources and send them to the FHIR server? Well, there are a few reasons.

In the first place, not every item in the form will result in a separate resource to be created. You still need somewhere to place the other data. You could have a hybrid approach where the Form Filler creates both a QuestionnaireResponse and the desired resources, but how will the Form Filler know which resources to create? Hard coding the FormFiller for each form type seems a bit clunky.

Which leads to the next point – the Q/QR approach is much easier for the Form Filler. In effect, it doesn’t need to do anything extra – beyond whatever processing it is doing to pre-populate and render the form, then create the QR. The extraction is transparent to it. If you didn’t do this, then the Form Filler would need to be separately coded for each type of form – not particularly scalable. So to create a different form with different resources to be extracted, you simply need to design the appropriate Questionnaire – job done!

That point about making life easier for the Form Filler cannot be overstated. Creating a bundle of resources with all the required references is not a trivial task, especially when a different set of resources is needed for each form and they need to reference other resources in the target FHIR server as well – such as the Patient or Practitioner. One of the design goals in FHIR is to move complexity to the server away from the client – on the grounds that there are a lot more clients than servers. This is a great example of this philosophy.

There’s also the matter of medico-legal aspects of this work. It may be necessary to re-create the form to establish what was entered, and without a QuestionnaireResponse resource this would be a daunting task. This also means that we likely want to include a Provenance resource in the mix – so we can unambiguously state which resources were extracted from each form instance – and to be able to update the form and the extracted resources in the event of error

With a Questionnaire we also get ‘portable’ form definitions – making it possible for a form to be designed once, and then used by multiple form fillers. This is great for national level deployments, where the organization needing the information can design the Questionnaire, then the systems capturing the information can more simply implement that form within their own systems – without any further effort if they can render the form and create the QuestionnaireResponse from the instructions within it. For example, take a look at some work the Australians are doing for their MBS715 form – and others.

And finally, the SDC IG is one of the most exercised IG’s in FHIR. It’s been in connectathons for the past 5 years or so (if not longer) and a tremendous amount of thought has gone into it by some of the leading lights within the FHIR community. It simply makes sense to take advantage of all that work.

It should also be pointed out that even if the Form Filler rendering the form can’t utilize the Questionnaire directly, the Questionnaire acts as a computable requirements ‘document’ – much better than a spreadsheet! And even if the form UI has to be manually created, by producing a single compliant QuestionnaireResponse instance it can still support resource extraction

So that’s enough theory. In the next post we’ll consider what an environment to support forms might look like, using the guidance from the SDC.

About David Hay
I'm an independent contractor working with organizations like Lyniate, CSIRO in Australia and the New Zealand Ministry Of Health. I'm an HL7 Fellow, Chair Emeritus of HL7 New Zealand and a co-chair of the FHIR Management Group. I have a keen interest in health IT, especially health interoperability with HL7 and the new FHIR standard.

2 Responses to FHIR Forms: Theory and background

  1. Pingback: Dew Drop – January 31, 2022 (#3610) – Morning Dew by Alvin Ashcraft

  2. Pingback: FHIR Questionnaire: Connectathon 6 | Hay on FHIR

Leave a Reply

%d bloggers like this: