
Quality Control: How To Validate Full FHIR Specifications In One Click
Subscribe to our newsletter
SubscribeSimplifier.net has long had one-click validation of any FHIR resource against the FHIR standard and profiles. With Quality Control we are adding one-click validation of your entire FHIR specification and validation against custom business rules in FHIRPath. This is available to customers on any of our paid plans right now.
See below for a breakdown of the feature or dive straight into the Quality Control documentation.
Bulk FHIR validation
As my colleague Ardon has covered extensively in his recent overview of FHIR validation on Simplifier.net blog post, we already have one-click validation of any FHIR resource available on the platform. This will validate conformance resources, like StructureDefinitions, ValueSets, etc., against the rules of the FHIR standard. It will validate example data against the FHIR profiles they claim to conform to while having clear errors and inline error-highlighting.

When you are building a real FHIR specification, it can get tedious to click Validate on every resource one-by-one. This is how errors slip through the cracks as well. This will no longer be the case! You will now see a Quality Control button on their projects with different rulesets to run over their entire project.
Select the minimal ruleset and we will check the most important rules:
- Whether all your canonicals are unique
- And bulk FHIR validation, checking each of your FHIR resources just like you would Validate them one-by-one.
In record time, about 500 resources per minute, you will have an overview of every item you can improve in a specification!

Custom business rules validation
The new ability to create and validate against custom business rules is even more powerful. Do you want to make sure the Publisher element of your profiles is always filled with your company name? You got it. Making sure every file with a filename ending in -ValueSet.xml
really is a ValueSet? No problem. Quality Control can check this with the push of one button.
Let’s look at some examples!

You will see here above a screenshot of a presentation from FHIR DevDays conference, where David Simons and Hans van Amstel showcased the extensive quality assurance test suite they put in place at Royal Philips. This is a great example of real-world Quality Control needs. Let’s see how a few of these can be implemented.
Building our first custom Quality Control rules
Let’s first start with the Quality Control rule. Hans checked if the canonical URLs of all conformance resources follow a certain pattern. He also makes sure they are unique. For this canonical URL pattern, let’s say we want to verify each of our StructureDefinitions and that the URL starts with our canonical base URL ‘https://fhir.example.org/’. Here is what such a rule might look like:
- name: canonical-starts-with
status: "Checking if canonical URL starts with correct base"
filter: url.exists()
predicate: url.startsWith('https://fhir.example.org/')
error-message: "Canonical URL doesn't start with correct base"
Based on this, you might see that a ruleset for Quality Control is a YAML file, containing a list of rules. Each of those rules can have a set of properties (like name
, status
, and error-message
), filters (such as filter
) as well as a set of actions (like predicate
). The order of elements within a rule does not matter.
The rule properties can be used in any rule and provide it with a unique name
, give a status
message to tell the user what rule is being evaluated. It can also give an error-message
that will be displayed when the error fails for the file that is being checked.
You don’t always want a rule to be checked against all files in your FHIR project but perhaps on a subset only. In this example, we only want to verify the canonical base URL for resources that have any canonical URL. Thus, we can filter
the only resources that meet this criterium and we do so with a FHIRPath statement. With url.exists()
we check if the resource currently being checked has an element named ‘URL. We will start our predicate check if this succeeds. Otherwise, we will just skip this fill for now.
The rule actions are where the real, well, action happens. The most common of all actions is the predicate
, which is again a FHIRPath statement. This statement will provide the actual judgment if a resource does or does not successfully pass our test. In this case, we want to know if the value of the url
element starts with ‘https://fhir.example.org/’. FHIRPath has a handy startswith
function for that: url.startsWith('https://fhir.example.org/')
.

We have now written our first FHIRPath based custom business rule! Go to your project, open the Quality Control drop-down and create a new rules file. Paste the rule we have just created, save the file and you will see your new ruleset available for use when you come back to the Quality Control drop-down. Clicking it will execute the check on each of your StructureDefinitions. ?
There are many different actions available for your Quality Control checks and continuing onto canonical uniqueness we will meet the unique
action. From the bulk validation paragraph, you saw that this check is already part of our minimal set of rules. Here is what it might look like for StructureDefinitions only:
- name: unique-canonicals
status: "Checking if all StructureDefinitions have a unique canonical"
filter: StructureDefinition.exists()
action: unique
unique: url
This can be added as a second rule to our previously created rules file. You will recognize the name, status, and filter elements. The filter here has a simple FHIRPath statement to check if the resource currently at hand is a StructureDefinition.
Then, there is the action unique
specified and this action also needs its own input to indicate which element should be unique within the project. In this case, it is the url
element.
The above should also give you all the tools to code the next two quality assurance rules Philips presented:
- Checking if a
description.exists()
- Making sure the
differential.exists()
, but thesnapshot.exists().not()
I will come back to the fourth rule in a later post. Filename-based filters and predicates are coming soon as well.
In our documentation, you can find more excellent examples of what is possible with Quality Control.
Testing your FHIRPath rules
To make sure your FHIRPath rules test what you intended them to test, it’s helpful to first test your statements on a few resources. Here are some of my favorite resources for that:
- Brian Postlethwaite’s FHIRPath Tester for Windows (XML)
Doesn’t support FHIR version 4.0.1 yet. It generally works if you update the fhirVersion in your pasted resource to 4.0.0. - Health Samurai and LHNCBC’s online JavaScript FHIRPath Tester (JSON)

Copy the resource of your choice to your clipboard in the format that you need (Download > Copy to Clipboard) and paste it in one of the testers. Then, test every FHIRPath statement to see if it works correctly. Start with testing every small part of your query and combine them to the filters and predicates you need.
Do you need more help? Our support team is here for you.
To conclude
Running bulk FHIR validation on your entire project is very powerful to prevent any errors in your FHIR specification. Even more when validating your custom business rules in one-click to enforce your organization’s custom profiling guidelines. But what could be more powerful? Running this anytime, anywhere, with zero clicks!
With Quality Control, you are able to run your full Quality Control rulesets on the command line with Firely Terminal after each change you make to your specification. And this even before saving it back to Simplifier.
Additionally, it will open using Quality Control in your Continuous Integration/Continuous Development pipelines!
Now please try out Quality Control and get those rules running!