0
votes

I'm consuming a FHIR bundle, and trying to resolve references to resources within the bundle, usin the .net FHIR R4 nuget package. I'm using this information as a reference.

How to resolve a reference in a Bundle:

  • If the reference is not an absolute reference, convert it to an absolute URL:
    • if the reference has the format [type]/[id], and
    • if the fullUrl for the bundle entry containing the resource is a RESTful one (see the RESTful URL regex)
      • extract the [root] from the fullUrl, and append the reference (type/id) to it
      • then try to resolve within the bundle as for a RESTful URL reference.
      • If no resolution is possible, then the reference has no defined meaning within this specification
    • else no resolution is possible and the reference has no defined meaning within this specification
  • else
    • Look for an entry with a fullUrl that matches the URI in the reference
    • if no match is found, and the URI is a URL that can be resolved (e.g. if an http: URL), try accessing it directly)

Note, in addition, that a reference may be by identifier, and if it is, and there is no URL, it may be resolved by scanning the ids in the bundle. Note also that transactions may contain conditional references that must be resolved by the server before processing the matches.

If the reference is version specific (either relative or absolute), then remove the version from the URL before matching fullUrl, and then match the version based on Resource.meta.versionId. Note that the rules for resolving references in contained resources are the same as those for resolving resources in the resource that contains the contained resource.

If multiple matches are found, it is ambiguous which is correct. Applications MAY return an error or take some other action as they deem appropriate.

The Bundle.FindEntry extension method appears to only work on absolute references such as this...

<entry>
    <fullUrl value="http://example.org/fhir/Observation/124"/>
    <resource>
        <Observation>
            <id value="124"/>

            <subject>
                <!--    this is reference to the first patient above    -->
                <reference value="http://example.org/fhir/Patient/23"/>
            </subject>
        </Observation>
    </resource>
</entry> 

...but it throws an exception if the reference is not absolute such as this:

<entry>
    <fullUrl value="http://example.org/fhir/Observation/123"/>
    <resource>
        <Observation>
            <id value="123"/>

            <subject>
                <!--    this is reference to the first patient above    -->
                <reference value="Patient/23"/>
            </subject>
        </Observation>
    </resource>
</entry>

Is there any functionality provided that can resolve relative references? Failing something already provided, How would I write my own?

  • How do you convert arelative url to absolute as stated should be done in the spec?
  • What would be the logic for extracting the root from the EntryComponent's FullUrl to resolve? How do I know what the root is?
  • How do I know that a reference is by identifier? it looks just like a relative reference.
1

1 Answers

1
votes

There is functionality for that in the .Net FHIR library already, in the form of extension methods on ResourceReference. For your example something like this could work:

    ResourceReference r1 = ((Observation)b.Entry[0].Resource).Subject;
    var abs = r1.GetAbsoluteUriForReference(b.Entry[0].FullUrl);

This takes the (relative) reference from the subject field in the source resource, and uses the source entry's fullUrl to combine the endpoint/root in that with the relative reference.

The root/base/endpoint will always be the part of the absolute url up to the resource type, but since that is sometimes hard to determine, the library offers you the ResourceIdentity functionality to build references or look at specific parts of them. See ResourceIdentity unit tests for many examples on that.

If a reference is by identifier, the .Identifier of the ResourceReference will be filled in. Or, if it is a conditional reference, the .Query of the ResourceIdentity will be filled.