Terminology services
Note
The features described on this page are available in all Firely Server editions.
Firely Server provides support for Terminology operations and validation against terminologies. This is done through a local implementation based on the Administration database (‘Local Terminology Service’) and - if configured - extended with external FHIR Terminology Servers (‘Remote Terminology Services’). The configuration allows you to set preferred services for each CodeSystem and ValueSet. Firely Server will then transparently select and query either the Local or one of the Remote Terminology Services.
Of the operations listed below the following can be supported by the Local Terminology Service: $validate-code, $expand, $lookup, $find-matches. Note that it only supports simple ValueSets and CodeSystems like the ones part of the FHIR specification. It cannot support complex terminologies like LOINC or SNOMED-CT.
The terminology operations can be invoked for different FHIR versions as specified in Multiple versions of FHIR.
Terminology Integration
In earlier versions of Firely Server, local terminology services were separately configured from so-called Terminology Integration. These are now merged.
Operations
ValueSet $validate-code
- definition:
- notes:
Available on the type level
<firely-server-endpoint>/administration/ValueSet/$validate-codeand the instance level<firely-server-endpoint>/administration/ValueSet/<id>/$validate-code.Only the parameters url, valueSet, valueSetVersion, code, system, display, coding, codeableConcept, abstract are supported.
The url and valueSetVersion input parameters are only taken into consideration if no valueSet resource was provided in the body. So the valueSet in the body takes priority.
Both
GETandPOSTinteractions are available.
ValueSet $expand
- definition:
- notes:
Available on the type level
<firely-server-endpoint>/administration/ValueSet/$expandand the instance level<firely-server-endpoint>/administration/ValueSet/<id>/$expand.Only the parameters url, valueSet, valueSetVersion and includeDesignations are supported.
The url and valueSetVersion input parameters are only taken into consideration if no valueSet resource was provided in the body. So the valueSet in the body takes priority.
Both
GETandPOSTinteractions are available.
CodeSystem $lookup
- definition:
- notes:
Available on the type level
<firely-server-endpoint>/administration/CodeSystem/$lookup.Only the parameters code, system, version, coding and date are supported.
Code & system combination takes priority over the coding parameter.
Both
GETandPOSTinteractions are available.
CodeSystem $find-matches / $compose
- definition:
- notes:
Available on the type level
<firely-server-endpoint>/administration/CodeSystem/$find-matchesand the instance level<firely-server-endpoint>/administration/CodeSystem/<id>/$find-matches.Only the parameters system, exact, version, property.code and property.value are supported.
The url and valueSetVersion input parameters are only taken into consideration if no valueSet resource was provided in the body. So the valueSet in the body takes priority.
Both
GETandPOSTinteractions are available.$find-matches was named $compose in FHIR STU3. The operation is supported with both names.
CodeSystem $subsumes
- definition:
- notes:
Available on the type level
<firely-server-endpoint>/administration/CodeSystem/$subsumes.Only the parameters codeA, codeB, system, and version are supported.
The system input parameters is only taken into when called on the type level.
Both
GETandPOSTinteractions are available.
ConceptMap $closure
- definition:
- notes:
Available on the system level
<firely-server-endpoint>/administration/$closure.This operation is passed on to a Remote Terminology Service supporting it. It supports any parameters that the Remote service supports.
Only
POSTinteractions are available.
ConceptMap $translate
- definition:
- notes:
Available on the instance level
<firely-server-endpoint>/administration/ConceptMap/[id]/$translateand the type level<firely-server-endpoint>/administration/ConceptMap/$translate.Only the parameters url, conceptMap (on POST), conceptMapVersion, code, system, version, source, target, targetsystem and reverse are supported.
Both
GETandPOSTinteractions are available.
Configuration
Pipeline
Make sure to add the Vonk.Plugins.Terminology plugin to the PipelineOptions in appsettings in order to make use of the TerminologyIntegration plugin.
Additionally, to the “/administration” pipeline, Vonk.Plugins.Terminology can be used on the regular FHIR pipeline “/”. Please note that in this case, CodeSystems and ValueSets are resolved from the Administration repository when executing a terminology operation and the corresponding resource is not provided as part of the request as a parameter.
"PipelineOptions": {
"PluginDirectory": "./plugins",
"Branches": [
{
"Path": "/",
"Include": [..]
},
{
"Path": "/administration",
"Include": [
"Vonk.Core",
"Vonk.Fhir.R3",
"Vonk.Fhir.R4",
"Vonk.Administration",
...
"Vonk.Plugins.Terminology"
],
"Exclude": [
"Vonk.Subscriptions.Administration"
]
}, ...etc...
To include or exclude individual operations in the pipeline, see the available plugins under Terminology.
Also make sure that the terminology operations are allowed at all in the SupportedInteractions section:
"SupportedInteractions": {
"InstanceLevelInteractions": "$validate-code, $expand, $compose, $translate, $subsumes",
"TypeLevelInteractions": "$validate-code, $expand, $lookup, $compose, $translate, $subsumes",
"WholeSystemInteractions": "$closure"
},
Lastly, operation on the administration endpoint can be limited to specific IP addresses:
"Administration": {
"Security": {
"AllowedNetworks": [ "127.0.0.1", "::1" ], // i.e.: ["127.0.0.1", "::1" (ipv6 localhost), "10.1.50.0/24", "10.5.3.0/24", "31.161.91.98"]
"OperationsToBeSecured": [ "$validate-code", "$expand", "$compose", "$translate", "$subsumes", "$lookup", "$closure" ]
}
},
Options
You can enable the integration with one or more external terminology services by setting the required options in the appsettings file. There is a block for the Local Terminology Service and one for each Remote Terminology Service.
For each terminology service you can set the following options:
- Order:
The order of the terminology service, or the priority. If multiple Terminology services could be used for a request, Firely Server will use the priority to select a service. Terminology services are arranged in a ascending order: so 1 will be selected over 2.
- PreferredSystem:
If a request is directed at a specific code system, Firely Server will choose this terminology server over other available services. A system matches one of the preferred systems if the system starts with the preferred system. So
http://loinc.orgwill match any CodeSystem or ValueSet with a canonical that starts with that url.- SupportedInteractions:
The operations supported by the terminology service. Firely Server will only select this service if the operation is in this list. Valid values:
"ValueSetValidateCode" "CodeSystemValidateCode" "Expand" "FindMatches" / "Compose" "Lookup" "Translate" "Subsumes" "Closure"- SupportedInformationModels:
The FHIR versions supported by the terminology service. Valid values:
"Fhir3.0" "Fhir4.0" "Fhir5.0"- Endpoint:
The endpoint url where Firely Server can redirect the requests to.
- Username:
If the terminology service uses Basic Authentication, you can set the required username here.
- Password:
If the terminology service uses Basic Authentication, you can set the required password here.
- ClientId:
If the terminology service uses a client_credentials-based OAuth2 flow, you can set the client_id here.
- ClientSecret:
If the terminology service uses a client_credentials-based OAuth2 flow, you can set the shared client secret here.
- Scopes:
If the terminology service uses a client_credentials-based OAuth2 flow, you can set the scopes requested by Firely Server here.
- MediaType:
Default Media-Type that should be used for serialization of the Parameters resources forwarded to the external terminology servie
Notes:
The Endpoint, Username and Password settings are not valid for the Local Terminology Server, just for the Remote services.
If a Remote Terminology Service has different endpoints for different FHIR versions, configure each endpoint separately.
The
SupportedInformationModelscannot be broader than the correspondingFhir.Rxplugins configured in the PipelineOptions.Firely Server automatically requests JWT tokens for an OAuth2-protected endpoint and ensures that a valid token is always submitted as part of the request to the external terminology service.
A sample Terminology section in the appsettings can look like this:
"Terminology": {
"MaxExpansionSize": 650,
"LocalTerminologyService": {
"Order": 10,
"PreferredSystems": [ "http://hl7.org/fhir" ],
"SupportedInteractions": [ "ValueSetValidateCode", "Expand" ],
"SupportedInformationModels": [ "Fhir3.0", "Fhir4.0", "Fhir5.0" ]
},
"RemoteTerminologyServices": [
{
"Order": 20,
"PreferredSystems": [ "http://snomed.info/sct" ],
"SupportedInteractions": [ "ValueSetValidateCode", "Expand", "Translate", "Subsumes", "Closure" ],
"SupportedInformationModels": [ "Fhir4.0" ],
"Endpoint": "https://r4.ontoserver.csiro.au/fhir/",
"MediaType": "application/fhir+xml"
},
{
"Order": 30,
"PreferredSystems": [ "http://loinc.org" ],
"SupportedInteractions": [ "ValueSetValidateCode", "Expand", "Translate" ],
"SupportedInformationModels": [ "Fhir3.0", "Fhir4.0" ],
"Endpoint": "https://fhir.loinc.org/",
"Username": "",
"Password": ""
}
]
},
This means if you execute a terminology operation request, Firely Server will check whether the request is correct, redirect it to the preferred terminology service and finally return the result.
Additionally to the remote and local terminology services, you can configure the maximum number of concepts that are allowed to be included in a local ValueSet expansion (MaxExpansionSize). ValueSets stored in the local administration database larger than the configured setting will not be expanded, hence they cannot be used for $validate-code, $validate or $expand.
License
The Terminology plugin itself is licensed with the license token http://fire.ly/vonk/plugins/terminology.
When you configure Remote Terminology Services it is your responsibility to check whether you are licensed to use those services.
Advanced Terminology with Conformance Archives (CAR files)
Note
The features described in this section require the Advanced Terminology license token http://fire.ly/advanced-terminology, which is separate from the base terminology license.
The local terminology service built into Firely Server works well for simple ValueSets and CodeSystems such as those shipped with the FHIR specification. However, large and complex terminologies like SNOMED CT and LOINC cannot be stored as plain FHIR resources in the Administration database — they are too large, have rich hierarchical relationships, and require specialised subsumption logic.
Conformance Archive (CAR) files solve this problem. A CAR file is a representation of a CodeSystem produced by the Firely.Car library. It stores the full concept inventory together with all required relationship data in a format that can be loaded and queried efficiently at runtime from the local filesystem — without requiring an external terminology server.
When AdvancedTerminologyConfiguration is active and at least one CAR file is configured, Firely Server registers a CAR Terminology Host alongside the existing local and remote terminology hosts. In addition, the default terminology implementation is replaced by the Delegated Terminology, which contains the following logic:
For every incoming terminology request, the proxy first checks whether the CAR Terminology Host can handle the request (i.e. whether the requested CodeSystem URL is present in one of the configured CAR files).
If the CAR host can handle the request, it serves it directly.
For ValueSet/$validate-code requests that involve complex filter criteria (e.g.
is-aordescendent-offilters referencing a CAR-backed CodeSystem), the proxy decomposes the request into a series of lower-level CodeSystem operations (CodeSystem/$validate-code,CodeSystem/$subsumes, andCodeSystem/$lookup) and aggregates the results.If the CAR host cannot handle a request (either because the CodeSystem is not in a CAR file, or because the operation is not supported), the request falls back to the standard terminology proxy and the configured local/remote services.
The following FHIR terminology operations are directly supported when the requested CodeSystem is backed by a CAR file:
CodeSystem/$validate-codeCodeSystem/$subsumesCodeSystem/$lookup
Operations that are not directly supported by CAR files (such as ValueSet/$expand, ConceptMap/$translate) will be handled by the fallback services (local or remote), just as before.
ValueSet/$validate-code is supported indirectly: if the included CodeSystem concepts are backed by a CAR file, the proxy automatically decomposes the validation into the supported CodeSystem-level operations listed above.
ConformanceArchives
Configure one or more CAR files in the Terminology:ConformanceArchives array in your appsettings.json:
"Terminology": {
"MaxExpansionSize": 650,
"ConformanceArchives": [
{
"Path": "/data/terminology/SCT.cs.car"
},
{
"Path": "/data/terminology/LOINC.cs.car"
}
],
"LocalTerminologyService": {
"Order": 10,
"PreferredSystems": [ "http://hl7.org/fhir" ],
"SupportedInteractions": [ "ValueSetValidateCode", "Expand", "FindMatches", "Lookup" ],
"SupportedInformationModels": [ "Fhir3.0", "Fhir4.0", "Fhir5.0" ]
}
}
- Path:
Absolute or relative path to the
.carfile on the local filesystem. All configured paths are validated at startup; Firely Server will refuse to start if a CAR file cannot be opened.
Note
If ConformanceArchives is empty or not configured, the CarTerminologyHost is not registered and no CAR-related behaviour is active. The standard local and remote terminology services continue to work normally.
Priority and fallback
The CAR Terminology Host is always consulted before other hosts for any CodeSystem that is present in a configured CAR file. If the CAR host cannot serve the request (unsupported operation or unrecognised system), the request is passed to the remaining terminology services in their configured order.
Startup validation
All configured CAR files are validated when Firely Server starts. A VonkConfigurationException is raised if any file is missing or cannot be read, preventing the server from starting with an invalid terminology configuration.
License
The Advanced Terminology feature requires its own license token, separate from the base terminology plugin:
Base Terminology (local + remote services):
http://fire.ly/vonk/plugins/terminologyAdvanced Terminology (CAR file support):
http://fire.ly/advanced-terminology
Both tokens must be present in your Firely Server license to use CAR-backed terminology together with the standard local and remote services.
When you configure CAR files it is your responsibility to ensure you hold the appropriate distribution license for the terminology content (e.g. a SNOMED CT National Release Centre license or a LOINC license).
