FHIR Versions and Conformance URLs

As you probably know, there are a number of ‘conformance’ resources in FHIR that have a unique ‘canonical’ Url that identifies them globally. Other resources that need to refer to them can do so by addressing them by that URL – for example when a profile (Core or Derived) binds a coded element to a ValueSet, it does so via that URL – as does a Profile referencing an Extension Definition (both Profile and Extension Definition are StructureDefinition resources).

Looking at the definition of the Url in the spec:

For StructureDefinition:

An absolute URI that is used to identify this structure definition when it is referenced in a specification, model, design or an instance. This SHALL be a URL, SHOULD be globally unique, and SHOULD be an address at which this structure definition is (or will be) published. The URL SHOULD include the major version of the structure definition.

For ValueSet

An absolute URI that is used to identify this value set when it is referenced in a specification, model, design or an instance. This SHALL be a URL, SHOULD be globally unique, and SHOULD be an address at which this value set is (or will be) published. The URL SHOULD include the major version of the value set.

So how do you accomplish this across different versions of FHIR?

Before we get into that, let’s just address that comment about the ‘major version’. In addition to the canonical URL, both ValueSet and StructureDefinition have a ‘version’ property. This is intended to be a ‘business version’ – i.e. when the contents of the resource change substantially, and is not the same as the FHIR versioning that occurs as resources are updated on a server. This is described in more detail here, but it’s basically a decision of the author when the business version changes – for example when you remove a concept from a ValueSet you may wish to change the version, but if adding a new one you may not.

So back to FHIR versions.

The issue around FHIR versioning starts to resolve when you separate the definition of the resources from its representation.

Take an example of a ValueSet  – say the set of iwi in New Zealand. (An iwi is a tribal affiliation for the Maori in New Zealand). At any point in time, there is a fixed set of iwi – you can get the list from here if you are interested. When we create the canonical URL for that ValueSet it is independent of the FHIR version – because when the FHIR version changes, the contents of the ValueSet does not.

So for this example we’d create a url like http://moh.govt.nz/fhir/ValueSet/iwi-1 – and it will remain the same regardless of FHIR version. The actual root of the Url will depend on who ‘controls’ the contents of the ValueSet – in this example we chose the Ministry of Health, but it might also be Stats New Zealand – or even HL7 New Zealand. For the purposes of this discussion it doesn’t really matter – just that we want it to be consistent across FHIR versions.

So far so good, but the spec states that it should also be the location of the resource – how will that work? As always, there are a number of ways that we could do that.

If we only ever supported a single version of FHIR then it would be simple – just host the ValueSet at the location http://moh.govt.nz/fhir/ValueSet/iwi-1. But that’s a rather naïve assumption to make. Until the resource is ‘normative’, then the structure may well change – and we can hardly expect every user of the resource to change versions at the same time.

An alternative is to host the resource at a version dependent url, but have an ‘http redirect’ that redirects from the ‘canonical url’ to the most recent one. In this way the resource can always be located using that url, but the previous versions are maintained and available. Of course, the onus is still on the client to go to the version-specific Url if they are not using the current version – but at least it is manageable. And once the resource does go normative, then we will no longer need the redirect – we could host directly at the url.

A complementary strategy is to also host the resource in a registry – the International FHIR registry (created by the good folk at Furore) is now available, and it’s really a no-brainer to place a copy there. Plus, of course there may be other registries – such as a National registry.

So to take our Iwi ValueSet example – and assuming that we need to host STU2 & 3 versions of the ValueSet, we now have:

(Note that in the hosting examples we are assuming that the logical Id of the resource is the same as the URL property. This is not required – but desirable).

If we create a profile or an extension containing an element that is bound to that ValueSet, then a client wishing to retrieve the ValueSet can either query directly for that ValueSet like so:

GET http://moh.govt.nz/fhir/ValueSet/iwi-1

This will return the most recent FHIR version of the ValueSet directly via a redirect to http://moh.govt.nz/fhir/stu3/ValueSet/iwi-1.

If they want a previous version, then they could go directly to the hosting endpoint:

GET http://moh.govt.nz/fhir/stu2/ValueSet/iwi-1

Or they could query the international registry like this:

GET https://registry-api.fhir.org/open/ValueSet?url=http://moh.govt.nz/FHIR/ValueSet/iwi-1

This will return a Bundle with (hopefully) a single resource.


After a couple of off-line conversations, I’ve come to appreciate that the desire for the URL’s to be directly resolvable is unlikely to occur widely until the resources themselves are normative – ie their structure will only change in ‘non-breaking’ way. We really don’t want the canonical URL’s to be version specific, and given that we need to expose them in a version specific way (ie with the FHIR version in the path), then the redirect suggested here is the only way I can see that will work if resolving directly – and it will only work for a single fhir version at a time. What it does bring home is that right now FHIR clients should be aware that they may not receive the version they expect – and plan accordingly (at least until normative!). At least, that is how clinFHIR works…

A better alternative right now is the use of Registries as described above – effectively repositories of these conformance resources indexed by URL. When a client wishes to retrieve a referenced resource, they query the registry for that resource using the canonical URL, rather than resolving the link directly. The registry could expose its search at version specific endpoints, thus allowing the client to specify the version they require.




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 FHIR Versions and Conformance URLs

  1. Peter Jordan says:

    David, Just to be clear, depending on the server implementation, TTBOMK those last 3 sample GET requests may only return the definition/metadata of the Value Set, not the concepts – particularly if it’s an intensional (query-based) Value Set. Retrieving the concepts from the later requires an expansion operation in which the URL is just one of the search parameters that might identify the value set (others could be the id, identifier or name).

    Furthermore, for those first 2 GET requests my server would treat the iwi-1 as the id of the value set, which suggests the need to include the version number in that id, yet we have a separate version property which can also be used as a search parameter. This seems to be conflating the issues of identification and versioning.

    Finally, the value in the url search parameter of the 3rd GET request looks to be incomplete.

  2. David Hay says:

    Hi Peter – yes, they would only return the VS resource itself – not the expanded contents if they were not in the actual resource – but the $expand would be able to do that surely?

    wrt including the business version of the resource in the id – this is because it’s actually a different resource (ie distinct to the one that it is superseding). The spec does recommend that it be included in the url – and implicitly in the id as well…

    wrt the url in the 3rd example – yes, a typo – I will correct – thanks!

    Interestingly, a colleague here at work pointed out that using the redirect may, in fact, be confusing to a client if it suddenly starts returning a resource with a different structure that what it was used to, so we may be stuck with fhir version specific urls after all. sigh.

  3. Peter Jordan says:

    Thanks David. Requests using the $expand operation will, of course, return the concepts. However, looking at Section “Technical v Business Versions” in the R3 spec at http://hl7.org/fhir/resource.html#id , there are are use cases where the Value Set id and version number are not the same (i.e. revisions) and the Value Set url properties do not include the version (and are not unique).

  4. Stewart Bailey-Smith says:

    Morning David, (my iwi is Ngāi Tahu by the way) so NHS Digital went round the houses a bit on this and have settled on the following that while ideal doesn’t look too bad a compromise.
    More detail can be found here: https://nhsconnect.github.io/gpconnect/development_fhir_api_guidance.html
    so we are getting this https://gpconnect.provider.thirdparty.nhs.uk/A12345/DSTU2/1/gpconnect/Patient/$gpc.getcarerecord/
    you can ignore the ODS Code part as that is just the identifier for the practice here. The version number (1 in the example) is the major version release, we won’t be supporting specific minor version requests so will supply the latest minor release version as they should be non-breaking changes only in the minor releases plus I imagine there will be a guaranteed minimum minor release as these go on so for example all providers must supply version 1.4 but may return higher as they are released. On a breaking change then a new release would have the new url of
    So long as we don’t end up in some sort of nightmare where we are supporting multiple FHIR Versions as well as numerous versions of message on each then it does give us a nice way to release changes and manage the clients transition through them.

  5. Peter Jordan says:

    Stepping aside from FHIR Versions, the issue of resource ids, identifiers, urls and versioning (particularly when conflated) has the potential to confuse implementers. It was certainly a topic of some debate on the Terminology Table at the San Diego Connectathon and it’s pretty clear that we need some Test Scripts that address those concerns and also follow the use cases in the spec referred to in my previous reply. The Value Set resource is an excellent test candidate as there are additional considerations around Code System versioning, e.g. where an entire Code System (such as SNOMED CT) is exposed as an Implicit FHIR Value Set.

  6. Lin Zhang says:

    As you probably know, there are a number of ‘conformance’ resources in FHIR that have a unique ‘canonical’ Url that identifies them globally

    What is the exact meaning of the word ‘globally’? Of / relating to / involving the entire world OR a whole?


    • Lin Zhang says:

      As you probably know, there are a number of ‘conformance’ resources in FHIR that have a unique ‘canonical’ Url that identifies them globally.

      • Lloyd McKenzie says:

        Unique across all systems. I.e. If you’ve got the Url, you should be able to resolve to exactly one resource instance.

  7. Lin Zhang says:

    Hi Lloyd,

    Thank you so much for your clarification.

    Lin Zhang

Leave a Reply