How-to's
10 Min Read

Custom Resources in Firely Server

Christiaan Knaap

Subscribe to our newsletter

Subscribe

Please note that this blog post was written before Vonk changed its name to Firely Server.

TL;DR;

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:

{
"AdministrationImportOptions": {
"SimplifierProjects": [
{
"Uri": "https://stu3.simplifier.net/education",
// "UserName": "your Simplifier user name",
// "Password": "secret",
"BatchSize": 20
}
]
}
}

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.

c:programsvonk>dotnet vonk.server.dll

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!

Test!

First, we will assert that the StructureDefinition was actually loaded. Pull up Postman and query:

GET http://localhost:4080/administration/StructureDefinition/Education 

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:

GET http://localhost:4080/Education

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:

GET http://localhost:4080/Education 
GET http://localhost:4080/Education/christiaan-maths

On a final note: Validation. In fact, you can validate your custom resource as well. That StructureDefinition is there for a reason, not?

GET  {{url}}/Education/christiaan-maths/$validate

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.

Wrap up

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.

Notes

Turn the Basic SD into a Custom Resource definition

This approach for creating a StructureDefinition for a Custom Resource is described in the Firely Server documentation.

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’

Want to stay on top of Interoperability and Health IT? 

Subscribe to our newsletter for the latest news on FHIR. 

Post a comment

Your email address will not be published. Required fields are marked *