Terminology Services in FHIR

I must admit I haven’t paid as much attention to Terminology as I should.

I do appreciate how important it is – most (if not all) resources in FHIR have multiple coded elements that refer to a terminology of some sort, and a common understanding of concepts is one of the key parts of interoperability, but until Grahame asked me to talk to this subject at the recent Brisbane Seminar & Connectathon, I’d regarded coded items as just another datatype.

But DSTU-2 brings a whole new set of possibilities to the picture, so let’s look at how that helps us.

Before we go into details – lets take a step back and talk about the relationship between ValueSets, Profiles and terminologies.

This picture (From one of Grahames presentations) shows at a high level these inter-relationships.

Screen Shot 2015-06-22 at 8.50.30 pm

Reviewing the main blocks in the picture:

The Code System box represents the terminology (eg SNOMED or LOINC).

A ValueSet resource selects a subset of that terminology for some specific purpose – in some context. For example it might be all the diagnosis codes in SNOMED – or it might just be the common ones in an ED situation (to make it easier for an ED clinician to select a diagnosis). The ValueSet is a deceptively complex beast, and can do a lot more than just a simple sub-set (such as defining its own codes), but you get the idea.

An Element Definition in a profile (to be precise a StructureDefinition resource) then ‘binds’ to that ValueSet – in effecting stating that the valid options for that element come from the indicated ValueSet. The binding ‘strength’ determines whether values that are not in the ValueSet can be selected (see details in the spec).

Finally a specific resource instance:

  • has a value from the terminology
  • and claims to be conformant to the profile (via the element definition)

This concept of ‘claiming conformance’ is an important one.

Remember that a profile (StructureDefinition) takes a base resource (itself defined by a StructureDefinition), and ‘adapts’ it to a specific scenario. It can remove elements, add new ones (Extensions) or – as in this case – change the binding of a coded element.

The example above was for an ED clinician, and what we want to do is to make it easier for the clinician to select the diagnosis from a set of the most common ones. If we wanted to ensure that the diagnosis was ONLY from that ValueSet, then we’d set the binding strength to ‘required’. Otherwise, ‘extensible’ is more appropriate. We’d probably adjust other elements as well – for example an identifier may not be needed, and we might want to add an extension for certainty.

If a specific resource instance has values that are consistent with those described in the profile – eg the code is from the ValueSet and it doesn’t have an identifier, then it can make a claim that it is conformant to the profile, and it does so using a Profile tag on the meta element. It follows, that a single resource can be conformant to any number of profiles.

Then, processes (like a Decision Support component for example) that have a requirement for resources confirmant with a specific profile can easily find them. Note the use of the work ‘claim’ above – a processing component should check that the claim is correct.

So that’s all just background – we will talk more about profiles in later posts, but for now let’s come back to one of the neat parts about ValueSets. You see, in DSTU-2 there is now the concept of Operations – like a procedure that can be invoked on a resource. These were added to support more complex operations than the simple REST-ful ones – for the technically minded, these are more like RPC (Remote Procedure Call) invocations. Some of these are defined in the spec, or you can define your own.

There are a number of operations defined in the spec whose purpose is to define the properties of a Terminology Server – a server with specialized functions suitable for managing access to Terminologies. The one that is the most immediately useful is the ValueSet Expansion.

In this operation, the client specifies a ValueSet and an optional filter, and the Terminology server returns a ValueSet with all of the concepts expanded – ie all the matching concepts with the description attached – suitable for inclusion in a drop-down or other selection box.

For example, Condition.code is bound to a ValueSet (with a strength of example) that can be found at:


If you enter that URL into a browser (or preferably a REST client), you’ll get back the definition of the ValueSet, similar to this (some details have been removed for clarity):

    "resourceType": "ValueSet",
    "compose": {
        "include": [
                "system": "http://snomed.info/sct",
                "filter": [
                        "property": "concept",
                        "op": "is-a",
                        "value": "404684003"

It includes all SNOMED codes where concept is-a 404684003

But now enter the following URL:


You’ll still get back a ValueSet – but now there is a new element in the ValueSet called expansion that contains all the concepts from the ValueSet whose name matched ‘asthma’. Neat huh? You can take that set and use it populate a UI – which is just what clinFHIR (the Clinical Connectathon tooling) does.

Try it out – from the front page of clinFHIR select ‘Resource Builder’, then any patient, and then Condition from the dropdown box at the top. If you click on the word ‘CodeableConcept’ against the Condition.code line, you’ll get a selection box into which you can enter any text. After a brief pause you’ll get a list of matching options. Change the text and the list of options changes.

This is the $expand operation in action – taking the text you enter, sending it to the Terminology Server for expansion, and displaying the resultant expansion in the drop down. If you click on the ‘Explore ValueSet’ link, you’ll be able to get close and personal with the ValueSet directly.

Screen Shot 2015-06-22 at 9.06.46 pm

So you can see how a realm – for example a country – can set up a FHIR based Terminology server and get context based, consistent diagnosis coding across the whole country.

There are also other operations for looking up the details of a concept from a code, determining if a given code is actually in a given ValueSet and also for mapping concepts when a specific system uses a different set that can be mapped to the main one.

So the terminology features in FHIR are deceptively impressive!

About David Hay
I'm an independent contractor working with a number of Organizations in the health IT space. I'm an HL7 Fellow, Chair Emeritus of HL7 New Zealand and a co-chair of the FHIR Management Group. I have a keen interest in health IT, especially health interoperability with HL7 and the FHIR standard. I'm the author of a FHIR training and design tool - clinFHIR - which is sponsored by InterSystems Ltd.

9 Responses to Terminology Services in FHIR

  1. Pingback: LOINC FHIR Vocabulary Service - Instituto HL7 Brasil

  2. Paul says:

    Hi, do you have something (like tutorial, advice, and so on) about a Terminology Service in FHIR implementation?

    • David Hay says:

      Hi Paul – what sort of advice are you after? I presume you are familiar with the section in the spec on this? – http://hl7.org/fhir/terminology-service.html

      This link – https://fhirblog.com/?s=terminology – gives the list of the stuff I’ve done here


      • Paul says:

        Thanks David for your reply. Yes i am familiar with the fhir terminology server specification, i’m currently take a look at the HAPI FHIR API. Do you know this API? I have to try to implement a terminology server.


      • David Hay says:

        Hi Paul – I’m familiar with it as a consumer – I use it in the clinFHIR resource builder and the Value Set builder, but not as a server (which is where the hard stuff is!) If not already subscribed, you’ll find the conformance chat (https://chat.fhir.org/#narrow/stream/conformance) a useful place to get advice whenneeded – and I’m sure that the community will be interested in what you are doing…


      • Paul says:

        Thanks David for your time, you do a great job with your blog, keep it up. Have a nice day.


  3. David Hay says:

    You’re welcome Paul – thank you for the kind words!


  4. Jeremy Morris says:

    Super useful – I’ve come back to this post at least 3 times

  5. conmotto says:

    Here’s a working open source client example done in AngularJS: https://quickterm.healthcreek.org

Leave a Reply

%d bloggers like this: