Subscribe to our newsletterSubscribe
Please note that this blog post was written before Vonk changed its name to Firely Server.
Firely Server supports Custom Resources. Define your own resourcetypes, store and validate them in Firely Server just like any other resource. But, don’t try to exchange them with others.
What are Custom Resources?
Custom Resources in this blog and to Firely Server are resources of a resourcetype not defined in the FHIR Specification. Nonetheless, they are normal resources. This means that they are defined by a StructureDefinition and are a specialization of DomainResource. They have all the common elements like an id, narrative, etc.
When (not) to use Custom Resources?
Een ander begrijpt niks van jouw zelf gedefinieerde blokken.
Did you understand the line above? If so, then you are Dutch or you used Google Translate. Either way, if you want to be interoperable you need to use a common language. And not a custom one. In the same way, Custom Resources are not for interoperability. Keep that in mind.
The intended use is when you use Firely Server as the platform for an application, and there is that 10% of data that won’t fit any of the FHIR resources. Still, it would be very inefficient if you need a second database for that 10%. We therefore decided to allow you to structure that data just like any official resourcetype, and store it in Firely Server just like any other resource. The rest of the blog will show you how to do that.
The official FHIR way to structure data not defined as a resourcetype is to use the resourcetype Basic and add extensions for any data that needs to fit in. However, a Custom Resource is a lot easier to map to code, and also a lot more readable. Still – a Basic resource may be interoperable, a Custom Resource certainly is not.
Example use case: Education
Let’s assume that you have an app where you want to record the education of people. In FHIR no resourcetype Education exists. (For Practitioner there is the element qualification – but that is beside the point of this example.) So in this blog, we will create the custom resourcetype ‘Education’ and save some Education resources to Firely Server.
All the FHIR requests for this example are listed in a Postman collection that you can use on your own Firely Server instance.
Write the definition of Education
There is currently (afaik) no tooling available to create a StructureDefinition for a custom resourcetype other than a text editor. A couple of hacks you can do are:
- adjust the StructureDefinition of an existing resourcetype, preferably Basic;
- use Forge to write a Logical Model and adjust the result in a text editor to make it a resourcetype.
Details on this are below, for now let’s just check the result. Of course Simplifier.net is the place to administer your definitions, and yes it can support the definition of a custom resource as well. I created the ‘Education’ project for this: https://simplifier.net/education. If you open the resource ‘Education’ you can check the requirements that a definition for Custom Resources must meet:
- kind = resource
- derivation = specialization
- base = DomainResource
- you can only use FHIR defined datatypes
You may note that the canonical url of the StructureDefinition starts with http://hl7.org/fhir, just like with the official resourcetypes. This looks odd for something you define yourself, but in STU3 the invariant sdf-7 on StructureDefinition enforces this. In R4 this limitation is removed and you are strongly encouraged to use a canonical that is actually in a domain you manage.
Of course Simplifier also renders all the elements nicely, so have a look at what elements are in this resource.
Get Firely Server
Since you are on the Simplifier.net website already, you may as well download Firely Server from it. Insider tip: Despite the order of the page, download and extract the binaries first. Then download the evaluation license directly into the directory with the Firely Server binaries. More documentation on getting started with Firely Server is in the documentation.
Make Education known to Firely Server
Firely Server has an administration endpoint (and database) that defines what resourcetypes, profiles and searchparameters it will handle. You can control that in several ways. Here we will connect Firely Server to our project in order to make it load the StructureDefinition straight from Simplifier. Create a file named ‘appsettings.instance.json’ in the binaries directory. In it, add the Simplifier project as a source for the Administration import:
// "UserName": "your Simplifier user name",
// "Password": "secret",
Since I made the project public, you don’t need a username/password for this connection. If you try this with your own private project, you do need to fill those in.
Now start Firely Server from the commandline.
In the log you should see that it is loading conformance resources from the Simplifier project. If you encounter any errors: The log file with more detailed logging can by default be found at %temp%/vonk-<date>.log.
Alternatively, you can start Firely Server vanilla and upload the StructureDefinition to the Administration endpoint interactively. The request for that is in the Postman collection. This way you actually add the endpoint for Education while Firely Server is running!
First, we will assert that the StructureDefinition was actually loaded. Pull up Postman and query:
This should return the StructureDefinition as it is on Simplifier.
The Postman collection also contains a request to generate a snapshot for this StructureDefinition. Even though it describes a custom structure, the definition itself can still be processed by the snapshot generator.
Since we defined a new resourcetype, there should be a corresponding endpoint on Firely Server as well. Let’s try:
As expected, the endpoint is valid and you get an empty Bundle. Firely Server dynamically added the endpoint based on the definition.
In the Postman collection, there are three examples of Education resources that show you (a) what these look like and (b) what your favorite software providers have studied 🙂 Try to run the PUT statements that upsert the three Education resources. You can then retrieve them all together, or individually:
On a final note: Validation. In fact, you can validate your custom resource as well. That StructureDefinition is there for a reason, not?
This also means that prevalidation works for custom resources. Prevalidation is a feature in Firely Server that allows you to control how strict Firely Server validates resources that are sent to it. So you can avoid developer or input mistakes by validating the resource as it is being stored.
In Firely Server, you can store Custom Resources just like any other resource. Without any coding, simply POST the definition to Firely Server. Because it is driven by StructureDefinitions you get a decent description that can be shared and managed through Simplifier.net. And Firely Server can validate the instances for you.
Two further improvements will turn custom resources into truly first-class citizens of the Firely Server world. Firstly you will also be allowed to add SearchParameters defined on your custom resource. And with SearchParameters comes chained search, _(rev)include, etc. The second is that custom resources within a Bundle can not yet be validated. This will be fixed in the next version of Firely Server.
Turn the Basic SD into a Custom Resource definition
Turn a logical model into a Custom Resource definition
- Start Forge and build a logical model called ‘Education’. Save it to disk.
- Open the generated file in a text editor and adjust:
- change ‘kind’ to ‘resource’
- change ‘type’ to ‘Education’
- change ‘baseDefinition’ to ‘http://hl7.org/fhir/StructureDefinition/DomainResource
- rename ‘snapshot’ to ‘differential’
- remove the first element ‘Education’