Responsibilities of a FHIR client
May 4, 2015 Leave a comment
As we start to do more ‘real’ work implementing FHIR here at Orion Health, we wind up making a number of implementation decisions about the interfaces we develop, and these – of course – influence how clients will use the services we create. Naturally, we will use the Conformance resource to document these, but it got me thinking about the overall responsibilities of a FHIR client.
While there is little doubt that FHIR is a whole lot easier than the alternatives to implement, nevertheless it is still about the exchange of healthcare information, and that is inherently complex. Despite the best efforts of the designers to move complexity to the Server rather than the Client, there are still often a number of different ways to do the same thing (or what seems like it – especially in these DSTU times), and this means that there are a number of responsibilities for a FHIR client beyond simply following the spec for resources and interactions.
Let’s look at some of them.
First off the block are extensions. One of the ‘selling points’ for FHIR, and the reason why the base resources are nice and simple is that FHIR has a built-in extension mechanism that allows specific implementations to add the properties they need that are missing from the resources – and for a client to understand extensions it doesn’t recognise. The implication of this is that clients processing a resource need to specifically look for extensions – and make decisions based on whether they understand them.
There are actually 2 distinct types of extension.
The ‘standard’ extension (where the property name is extension) is one that contains information that might be useful to a client, but is safe to ignore if it is unrecognised by the client. For example we might want to record a patients religious affiliation in a Patient resource. Potentially interesting information – but not critical for the delivery of healthcare. (Of course, some religions may have healthcare consequences – like a Jehova’s Witness declining a blood transfusion – but you’d likely represent that directly – perhaps as a Flag – rather than inferring it from the religion).
The specification doesn’t dictate what a client should do with an unknown extension. There’s a strong recommendation that the narrative of a resource should contain the meaning of the extension so that it can be at least displayed to a user – but it is the decision of the implementer.
It’s also important to appreciate that extensions can occur at many positions within a resource:
- As a new element
- As a modification of an existing property (e.g. a more specific status code)
- Even a datatype can be extended – like an addess.
‘Modifier’ extensions are a different beast. These represent information that a client must understand for reasons of clinical safety. For example, you might want to assert that a patient does not have a specific condition, and so create a ‘negative’ (‘has not got’) extension. Another example might be asserting that a patient does not have a truncal rash. Obviously this completely changes the meaning of the resource, and it would not be clinically safe to ignore it. These extensions have the name ‘modifierExtension’ and the specification is quite explicit that an implementer must:
- Understand what the extension means or
- Refuse to the process the resource or
- Display a warning to a human to make a decision.
There’s more detail in the spec – you should be familiar with it.
ModifierExtensions are more limited about where they can occur – in particular they cannot modify properties that contain data – which means that they are at the level of the resource or ‘classes’ in the UML diagram.
The takeaway is that a client must always look for extensions – especially modifierExtensions.
The next thing to think about are references to other resources. FHIR is all about links between resources (sometimes referred to as a ‘web’ or ‘graph’ of information) so knowing how to ‘follow’ a reference is important for any client. There are 2 broad ‘categories’ of reference.
The most commonly used (and preferred) is the reference to a separate resource, which could be on the same server as the focal resource or a different server. Every resource has an unambiguous id, but the mechanism of actually retrieving it will vary. There might be a copy of the resource in a bundle that the client already has (perhaps a FHIR document or message) or it may be that the client needs to directly retrieve it from a server.
The second place for a linked resource is actually within the focal resource – the so-called ‘contained’ resource. This is used when the linked resource has no independent existence – for example a MedicationPrescription may have a contained Medication resource, if the host system only uses a drug code. You can tell that the resource is contained as the reference ID will begin with a hash (#) symbol, but the contained resource is otherwise identical to its independent brethren (with the exception that it cannot have a text property – the text of the contained resource should be in the text of the parent resource, and you cannot nest contained resources – ie a contained resource can’t have another contained resource in it.).
There is more detailed about contained resources in the latest version of the spec.
Oddly enough, one thing that a client doesn’t generally need to be concerned with is Profiles (unless it is creating resources that are supposed to be conformant to a profile). This is because a Profile is basically a statement about how a resource/s is being used to meet the requirements of a specific use case – quite deliberately any resource should be able to be processed without knowing what profiles it is supposed to be conformant to (of course, if a client is expecting a resource to be conformant, and it is not then that is another matter) – but specifically a profile cannot create a ‘default’ value that a client is expected to apply if not present in a specific resource.
Which actually leads quite nicely to another responsibility – don’t make assumptions. Even if a resource claims to be conformant to a particular profile, a client should always check. For example if a resource claims to be conformant with a profile that has made an optional property mandatory (eg Patient.identifier) – the client must always check, and be prepared to deal with any errors or omissions. Coded elements are another example – just because a profile might mandate a specific terminology/ValueSet doesn’t mean that a resource has obeyed this constraint.
Well, that’s about all I can think of at the moment – when I started this post I thought there might be more, but basically if comes down to:
- Look for extensions (especially modifierExtensions) and have a strategy for dealing with those you don’t recognize.
- Be aware that referenced resources could be in different places
- Don’t make assumptions
Oh, and if I have missed anything important – please leave a comment!