As readers will know, I’m a big fan of FHIR Shorthand as a way of making it much easier to create Implementation Guides and examples in conjunction with the IG publisher. In fact, I’m coming to the conclusion that all systems that expose FHIR API’s should have an IG that describes it (along with the CapabilityStatement resource of course) – and unless you have experience with creating StructureDefinitions directly, then FSH – and SUSHI – is the way to go.
Of course, creating IG’s is still not easy (it’s just easier) so I thought it would be a good idea to write about common patterns that you might want to express – and serve as a reminder for me when I forget!
So here’s the first one.
Suppose you are hosting a FHIR API that can create or update Patient resources and you want to say:
All patients must include their medical records number (MRN). Other identifiers are allowed, but the MRN must be present.
In order to do this, you’ll need to ‘slice’ the Patient.identifier element. Slicing is conceptually quite simple. It involves taking an element that can repeat – like the patient identifier – and create individual ‘slices’ each of which has specific characteristics – such as that it must be present. In this example you want to create a specific slice that describes the MRN, and make it required.
Slicing can become very complex, but fundamentally you define a ‘discriminator’ – which describes how to distinguish different slices from each other. There are a number ways of doing this, but a simple one is using the value of the slices as the discriminator.
So in our example, we’re slicing the Patient.identifier element, which uses the Identifier datatype. This datatype has 2 key sub-elements (there are others):
The system, which is a url that defines the ‘namespace’ within which the value of the identifier is unique.
The actual identifier value.
So when someone issues an MRN, the namespace that it is unique within is identified by the system url. Examples outside of healthcare include drivers licenses and passports – the issuer of those identifiers will have a system value so that a client knows what the identifier means.
How the system values are created and tracked is beyond the scope of this post – some are defined by the spec, but it’s possible for anyone to create one if needed.
So in our example, we want to set the discriminator to use the system sub element to distinguish between slices, and then specify that there must be one (and only one) identifier in a conformant resource that has that system.
Here’s how you do that in sushi.
Line 1 gives the profile name (which will also be the id of the StructureDefinition that is produced by SUSHI)
Line 2 indicates that the new profile is constraining the core Patient profile. (It’s quite common for profiles to constrain other profiles rather than core – often when there is a base national set of profiles – like US core or Australia base)
Lines 7 to 9 is where the discriminator is defined. We say that it’s the value of the system subelement that distinguishes between slices, and that it’s OK to have identifiers that are not explicitly defined in the profile (line 9).
In lines 12-13 we indicate that there is a single slice named NHI. There’s nothing to stop us having other named slices as well if we wanted to. For example, we might want to specify the specific set of identifiers that we allow – in which case there would be named slice for each one, and line 9 (slicing rules) would have the value ‘closed’.
And finally in line 15 we specify that the NHI slice must have the value ‘https://standards.digital.health.nz/id/nhi’. Note that it has the word ‘(exactly)’ on the end. We need this as we are specifying the exact uri that should be present in the instance.
Note that for this profile I included a couple of example Patient instances – one that should pass validation in the IG builder (or using the $validate operation if POSTed to a server) and another that should fail. This is a good way to ensure that you have defined it the way you meant to.
When sushi builds the instance, it adds the profile that it is claiming conformance to (see lines 20 and 29) in the resource meta.profile element as shown in the diagram below. This is how the validator knows to check that it actually is conformant.
The validator function within the IG Publisher QA report does extremely detailed validation. You’ll want to remove – or comment out – the failing example when you’re sure that everything is working as expected.
I hope you find that useful – I’ll add others as they come to mind. If there are other patterns you’d like to talk about then let me know in the comments and I’ll see what I can do.