FHIR Chat · Should canonical references with a pipe resolve? · implementers

Stream: implementers

Topic: Should canonical references with a pipe resolve?


view this post on Zulip Eric van der Zwan (Jan 05 2021 at 13:22):

I'm trying to validate QuestionnaireResponse with a canonical reference with a '|' (pipe). But it doesn't work yet (not found). if in my questionnaireResponse is a canonical reference to a http://myfhir.server/Questionnaire/covid19|2.2, how would the instancevalidation then work?

will it
A) directly try to resolve by sending a GET to url http://myfhir.server/Questionnaire/covid19|2.2? And should i first parse the request in order to get the business version (2.2) from the url?
B) make a search available a search with http://myfhir.server/Questionnaire/covid19|2.2 and try to return a bundle with searchresults?
C) something else?

Maybe there are some examples (java) with canonical url's in combination with valuesets, codesystems or questionnaire responses?

Thx

view this post on Zulip Lloyd McKenzie (Jan 05 2021 at 15:49):

I don't think the validator tries to resolve the URLs - it looks in the IG packages made available to the validator. (Hitting arbitrary URLs is somewhat of a security risk, though I think there's a way to make it try). If it were going to resolve, it would first hit known registries doing a search by URL and version and if it doesn't find that, should then search on the server endpoint implied by the URL using the same criteria. @Grahame Grieve can you confirm current behavior?

view this post on Zulip Grahame Grieve (Jan 05 2021 at 21:08):

I think the sequence is:

  • look in any provided packages
  • hit provided URL
  • hit the provided URL converted to a URL search if it looks like a restful API URL

view this post on Zulip Josh Mandel (Jan 05 2021 at 22:42):

if it looks like a restful API URL

To be clear: this implies that canonicals needn't be dereferenceable URLs, and indeed they might not even look like dereferenceable URLs. Is that right? (This came up with @Eric Haas in #subscriptions recently.)

view this post on Zulip Elliot Silver (Jan 05 2021 at 23:18):

There was also a question on #conformance recently about a urn as a canonical (urn:iso:3166 or similar) . Those definitely won't resolve, with or without a pipe.

view this post on Zulip Grahame Grieve (Jan 06 2021 at 00:26):

they don't need to be, though HL7 published ones always are

view this post on Zulip Michael Lawley (Jan 06 2021 at 00:26):

'|' is not a safe character in a URL -- I would not expect it to be resolvable / accepted by many libraries

view this post on Zulip Eric van der Zwan (Jan 06 2021 at 10:52):

I apollogize for the long post in advance. I like to work with examples since they usually work better. I'm aware that most things need maintenance and have a history. In order to use (older) information you need to know how it was created. Here versions of a questionnaire comes in handy. However not all changes in the questionnaire are changes to the meaning of the questionnaire. Luckly the questionnaire has a business-version as well. When a reference is needed to a spefic business-version of a resource, an canonical url can be used. With a pipe a version can be added to the url. The question is how this canonical including a version should be used? And maybe more specific: how to used them when validating resources?

I'm trying to validate a QuestionnaireResponse. To do so i need to know which questionnaire was used, which is referenced with a canonical including a business-version. Let me create a simplified example. For a long-running project i need to know if a patient is a intensive care or a medium care patient.

-- Phase 1 --

Simple codesystem
<CodeSystem>
<id value="patienttypecode"/>
<meta>
<versionId value="3"/>
</meta>
<url value="http://myfhir.server/CodeSystem/patienttypecode"/>
<version value="2.0">
<concept>
<code value="IC">
<definition value="Intensive Care Patient"/>
</concept>
<concept>
<code value="MC">
<definition value="Medium Care Patient"/>
</concept>
</CodeSystem>

Create a valueset using the codesystem
<ValueSet>
<id value="patienttypevalue"/>
<url value="http://myfhir.server/CodeSystem/patienttypevalue"/>
<version value="1.1"/>
<compose>
<include>
<system value="http://myfhir.server/CodeSystem/patienttypecode"/> <-- not canonical
<version value="2.0"/> <-- pointing to the business version of the code system.
</include>
</compose>
</ValueSet>

Creating a questionnaire using the valueset as choices for an answer
<Questionnaire>
<id>123</id>
<meta>
<versionId value="44"/>
</meta>
<url value="http://myfhir.server/Questionnaire/123"/>
<version value="5.0"/>
<item>
<linkId value="pattype"/>
<text value="WHAt is the type of patient?"/> <-- oeps wrong capitals.
<type value="choice"/>
<answerValueSet value="http://myfhir.server/CodeSystem/patienttypevalue|1.1"/>
</item>
</Questionnaire>

Creating a questionnaireResponse using the codesystem.
<QuestionnaireResponse>
<questionnaire value="http://myfhir.server/Questionnaire/123|5.0"/>
<item>
<linkId value="pattype"/>
<answer>
<valueCoding>
<system value="http://myfhir.server/CodeSystem/patienttypecode"/>
<code value="IC"/>
</valueCoding>
</answer>
</item>
</QuestionnaireResponse>

-- phase 2 --
I have noticed i have used capitals where i did not want them. So i modified the questionnaire by correcting the capitals in the definition. Since there is no breaking change, i won't change the business-version and keep it "5.0". Saving it will create a new instance:

<Questionnaire>
<id>123</id>
<meta>
<versionId value="45"/> <-- new instance, so incremented the versionId
</meta>
<url value="http://myfhir.server/Questionnaire/123"/>
<version value="5.0"/>
<item>
<linkId value="pattype"/>
<text value="What is the type of patient?"/> <-- corrected the typo's.
<type value="choice"/>
<answerValueSet value="http://myfhir.server/CodeSystem/patienttypevalue|1.1"/>
</item>
</Questionnaire>

Since the business-version is still "5.0", no futher actions are needed to the other resources. Nothing else changes in the meaning of the questionnaire or the response to it. Keep in mind that there are now two instances for the questionnaire with the canonical http://myfhir.server/Questionnaire/123|5.0.
When trying to validate the QuestionnaireResponse, the Questionnaire is needed. However the canonical is pointing to two resource instances now.

Question is: which instance is used for the validation.

In this case it would not matter which instance is used.
i would suggest that will always be the last updated. I can not find it in the documentation though.

-- phase 3 --
Everything is running well for a while, when suddenly there is a need for an extra patient type. The concept "High Care Patient" is needed and added to the codesystem. This i consider a big change, so the business version of the code system is incremented to "3.0".

<CodeSystem>
<id value="patienttypecode"/>
<meta>
<versionId value="4"/>
</meta>
<url value="http://myfhir.server/CodeSystem/patienttypecode"/>
<version value="3.0"> <-- incremented
<concept>
<code value="IC">
<definition value="Intensive Care Patient"/>
</concept>
<concept>
<code value="MC">
<definition value="Medium Care Patient"/>
</concept>
<concept>
<code value="HIGH">
<definition value="High Care Patient"/> <-- new concept added
</concept>
</CodeSystem>

Now we have a new concept in the codesystem. In order to use it in questionnaire, we also need to update the valueset since it is pointing to version "2.0". Since the include changes due to the new concept, i'm also updating the business-version from "1.1" to "1.2".
<ValueSet>
<id value="patienttypevalue"/>
<url value="http://myfhir.server/CodeSystem/patienttypevalue"/>
<version value="1.2"/> <-- new business version
<compose>
<include>
<system value="http://myfhir.server/CodeSystem/patienttypecode"/>
<version value="3.0"/> <-- updated to point to the new business version.
</include>
</compose>
</ValueSet>

The questionnaire now have to be altered in order to use the updated valueset. Since i need to recognize if there where 2 or 3 options, i will change the business version of the questionnaire to "5.1".
<Questionnaire>
<id>123</id>
<url value="http://myfhir.server/Questionnaire/123"/>
<version value="5.1"/> <-- small increment
<item>
<linkId value="pattype"/>
<type value="choice"/>
<answerValueSet value="http://myfhir.server/CodeSystem/patienttypevalue|1.2"/> <-- changes from 1.1 to 1.2
</item>
</Questionnaire>

The updated questionnaire is released. Now we are receiving both 5.0 and 5.1 versions of the questionnaire. When processing i will havev to save this information. So i can identify which questionnaires had only two answer options (and so the high care patient was marked either medium or intensive) and which had all tree.
In this example i have now 3 instances of the questionnaire/123; two with business-version 5.0 and on with version 5.1.

Questions is: how does the instancevalidation validate the (same phase 1) QuestionnaireResponse now?

Just hitting the URL (http://myfhir.server/Questionnaire/123) would 'fail', since that will just resolve to the lasted instance of the resource (=5.1). Technical it now won't fail since all previous concepts still exists, but what is a concept was removed?

Personally i would like to see a 'rule', which would state somehting like 'if a canonical with a version is used, it will resolve to the latest instance of that business-version.' In other words: the combination of resource id and business-version should be unique and thus resolve to just one instance. With this 'rule' vailidation is always done with the proper business version.

Although here i use the questionnaire as an example. The canonical's are use in more places and pointing to resources which have business-versions and (likely, i didn't check) to resources without. When a canonical is used, the version is probably important although i don't have the full perspective of all resource if this would break something elsewhere.

Could you tell me:

  • if my example follows the correct process of maintaining resources such as valuesets/codesystems/questionnaires/
  • if i'm using the business-verison correctly in my example
  • if the validation should honour the business-version (or fail it can not be found)
  • if my suggestion of letting a canonical url including a version resolve to the lastest saved instance with that business version, is a valid one?
  • and if this is just for the instancevalidation?
  • '|' is not a safe chararcter as @Michael Lawley mentioned. Maybe a canonical should look more like questionnaire/123/businessverion/5.1?

Thank you.

view this post on Zulip Michael Lawley (Jan 06 2021 at 14:36):

To be pedantic, they're not URLs, they are URIs. But if they look like a URL and you attempt a GET to resolve it, then I would expect you'd at least first want to %-encode the | symbol. Alternatively, if you're operating on a heuristic like "it looks like a restful API URL", then by the rules of FHIR ids, they cannot include a | so you'd actually want to strip off the version part first (and probably then check that it matches the business version if you do successfully retrieve a Resource).

view this post on Zulip Lloyd McKenzie (Jan 06 2021 at 17:25):

This is actually a canonical reference - so you should be stripping off the vertical bar and trailing text - as it's referring to a version, and is NOT referring to the canonical URL of the resource. There is not (and never was) an expectation that a canonical reference with URL would resolve. If you'd like to see guidance to that effect included in the spec, you could submit a change request.

view this post on Zulip Eric van der Zwan (Jan 06 2021 at 20:32):

So a canonical reference is referring to a version, but that can not be used in order to validate the resource since one should strip off the pipe and trailing text. i am probably missing something (sorry), but what then is the use of having the pipe and version in the canonical? A computer/server/client can not use that?
Secondly: the questionnaire.version should never change. If this needs to change, one would have save the resource as a new instance with a new ID which has the result of having a new url which then can be used voor validation.
Correct?

view this post on Zulip Michael Lawley (Jan 06 2021 at 22:41):

  1. canonical references allow you to reference a specific business version of a resource _relative to it's URI_ (which is not the URL where it might happen to be stored / available).
  2. yes, but we're talking about URIs (identifiers) not URLs

There is a lot of very confusing terminology in the FHIR spec. around URLs, URIs, logical URLs, canonical URLs, Canonicals, canonical references, etc etc. It would be really useful to have a dedicated page that disambiguates them all quite clearly, although I'm sure people will continue to mis-use the terms in forums, it might at least help get consistent use of the language throughout the spec and perhaps even in various IGs.

view this post on Zulip Lloyd McKenzie (Jan 07 2021 at 03:01):

The expected way to use a canonical reference is to query for it (by url & version) in a local repository or some shared registry. On the official server where the resource is maintained, the natural RESTful id of the resource probably wouldn't jive with the canonical URL because there could well be multiple instances of that same artifact (each a different version), and only one instance could exist with that id. To the best of my knowledge, even the HL7 site doesn't support resolving references that include the pipe in the URL. If you query by just the canonical, you'll get the 'current' release.

view this post on Zulip Aleksandra Pavlyshina (Jan 21 2021 at 12:03):

Grahame Grieve said:

I think the sequence is:

  • look in any provided packages
  • hit provided URL
  • hit the provided URL converted to a URL search if it looks like a restful API URL

Hi Grahame :smiley: ,
Could you please advise, what can be done on an IG site side, so that the FHIR Validator was able to fetch a profile by the provided canonical URL without passing the -ig parameter? From your post I assume it is possible, isn't it?

For example, The official URL for my profile is: https://semalexa.github.io/igpopdemo/StructureDefinition/AdverseEvent.
The https://semalexa.github.io/igpopdemo/StructureDefinition/AdverseEvent URL resolves to the https://semalexa.github.io/igpopdemo/StructureDefinition/AdverseEvent.html page.
The https://semalexa.github.io/igpopdemo/StructureDefinition/AdverseEvent.json file is located near the .html page.
@Grahame Grieve

view this post on Zulip Aleksandra Pavlyshina (Jan 21 2021 at 12:04):

This is the validator output:

$ java -jar validator_cli.jar -version 4.0.1 resourcesToValidate/AZAdverseEventSample.json -tx n/a -profile https://semalexa.github.io/igpopdemo/StructureDefinition/AdverseEvent
FHIR Validation tool Version 5.2.16 (Git# f815bc8fb8f0). Built 2021-01-14T22:39:23.297Z (6 days old)
  Java:   14 from C:\Program Files\Java\jdk-14 on amd64 (64bit). 3028MB available
  Paths:  Current = D:\Work\Healthsamurai\az-fhir-profiles, Package Cache = C:\Users\admin\.fhir\packages
  Params: -version 4.0.1 resourcesToValidate/AZAdverseEventSample.json -tx n/a -profile https://semalexa.github.io/igpopdemo/StructureDefinition/AdverseEvent
Loading
  Load FHIR v4.0 from hl7.fhir.r4.core#4.0.1 - 4575 resources (00:10.0228)
  Load hl7.terminology#2.0.0 - 3749 resources (00:02.0579)
  Terminology server null - Version n/a: No Terminology Server (00:00.0000)
  Get set...  go (00:00.0089)
  Fetch Profile from https://semalexa.github.io/igpopdemo/StructureDefinition/AdverseEvent
Exception in thread "main" org.hl7.fhir.exceptions.FHIRFormatError: This does not appear to be a FHIR resource (wrong namespace 'http://www.w3.org/1999/xhtml') (@ /)
        at org.hl7.fhir.r5.formats.XmlParserBase.parse(XmlParserBase.java:135)
        at org.hl7.fhir.r5.formats.XmlParserBase.parse(XmlParserBase.java:120)
        at org.hl7.fhir.r5.formats.ParserBase.parse(ParserBase.java:61)
        at org.hl7.fhir.validation.ValidationEngine.loadProfile(ValidationEngine.java:854)
        at org.hl7.fhir.validation.ValidatorCli.doValidation(ValidatorCli.java:230)
        at org.hl7.fhir.validation.ValidatorCli.main(ValidatorCli.java:159)

view this post on Zulip Aleksandra Pavlyshina (Jan 22 2021 at 13:25):

@Grahame Grieve

view this post on Zulip Lloyd McKenzie (Jan 22 2021 at 14:20):

Grahame's on PTO until the end of month, so it may take time for him to get back to you.

view this post on Zulip Grahame Grieve (Feb 02 2021 at 21:32):

this is on my todo list

view this post on Zulip Grahame Grieve (Feb 04 2021 at 03:14):

so the validator makes a request of https://semalexa.github.io/igpopdemo/StructureDefinition/AdverseEvent with the accept type set to application/json. The server needs to return json, not html


Last updated: Apr 12 2022 at 19:14 UTC