FHIR Chat · Resource ambiguity with Literal References · implementers

Stream: implementers

Topic: Resource ambiguity with Literal References


view this post on Zulip Robin Arnold (Nov 16 2020 at 15:58):

Literal references can be specified as a logical id without the resource type e.g. 'abc1234'. Also, logical-ids are only required to be unique for a given resource type, so I could have a Patient resource 'abc1234' and a RelatedPerson resource 'abc1234'. This could cause problems with compartment membership because the same reference field is used to model relationships to more than one type of resource. For example, CareTeam.participant indicates that the CareTeam resource belongs to a given Patient compartment as well as a RelatedPerson compartment. If the same logical-id were used for both a Patient and a (perhaps completely unrelated!) RelatedPerson 'abc1234'. this would map a CareTeam resource into a compartment it might not actually belong to.

Forcing relative references to include the resource-type is one solution, but deviates from the specification. Has anyone else hit this and is there a recommended approach?

view this post on Zulip Lloyd McKenzie (Nov 16 2020 at 16:00):

Logical ids should be a combination of system + value - and together those SHOULD be globally unique across all resource types.

view this post on Zulip Paul Church (Nov 16 2020 at 16:01):

A literal reference without the type isn't legal. There are some contexts where you can use id alone, for example reference search, but each of those contexts has some language like "Servers SHOULD reject a search where the logical id refers to more than one matching resource across different types" to clarify what happens.

view this post on Zulip Lloyd McKenzie (Nov 16 2020 at 16:01):

That said, it's certainly possible for the logical identifier to exist on multiple. E.g. pointing by social security number and it resolving on Patient, RelatedPerson and Practitioner. The reality is that logical references aren't as precise as true references. Even if you add resource type, there's a possibility of multiple matches.

view this post on Zulip Robin Arnold (Nov 16 2020 at 16:14):

@Paul Church yes, I agree that the search specification indicates that the search should be rejected if the logical id matches more than one resource across different types, but it provides a way to disambiguate such cases by specifying the desired type in the search string. But this still leaves the issue with compartment membership.

view this post on Zulip Robin Arnold (Nov 16 2020 at 16:18):

@Paul Church perhaps I'm misreading the spec, but it does seem as though literal references don't require the type. "For this reason, the reference may indicate directly the target resource type".

view this post on Zulip Paul Church (Nov 16 2020 at 16:33):

I read the spec as requiring the type in any case where it can't be inferred, because of "a Reference always point[s] to another resource, which has a fixed and known type".

I don't think this is entirely clear from the wording though. The "may indicate directly" wording points in the opposite direction. The Google implementation does not allow the type to be omitted in any case.

view this post on Zulip Lee Surprenant (Nov 16 2020 at 16:34):

To me, the spec is clear that relative references should be of the form ResourceType/123.
However, I don't see anything in the datatype definitions (i.e. no constraints other than the one about starting with #) that enforces that.

view this post on Zulip Lee Surprenant (Nov 16 2020 at 16:37):

We know absolute references are allowed as well, and that these need not match the FHIR REST API pattern. But would it still be possible to add some kind of URI pattern constraint?

view this post on Zulip Lee Surprenant (Nov 16 2020 at 16:38):

and, without this type of enforcement, is an opaque string value truly "invalid"?

view this post on Zulip Lloyd McKenzie (Nov 16 2020 at 16:56):

The section on references makes clear what the URL is allowed to be. It's either an absolute URL, it's a type/id or it's a local reference (starts with '#'). A bare id is never legal.

view this post on Zulip Paul Church (Nov 16 2020 at 16:58):

There is no part of that section that clearly states the type/id part of what you just said.

view this post on Zulip Lee Surprenant (Nov 16 2020 at 17:02):

also, what constitutes a valid absolute URL. does it need to match scheme ":" hier-part [ "?" query ] [ "#" fragment ] ?

view this post on Zulip ryan moehrke (Nov 16 2020 at 17:03):

I'm not sure where I got the impression (I tried to look for anything to back this up) but I was under the impression that a reference that is bound to only one resourceType by the base fhir spec is allowed to not give the resource type in the reference (i.e. Patient.managingOrganization=123 implies Organization/123 but Patient.generalPractitioner=123 is invalid because of this very reason) is this not the case?

view this post on Zulip Lee Surprenant (Nov 16 2020 at 17:04):

@ryan moehrke there are two different parts to this.

  1. what appears in the Resource
  2. what you can use to search it

view this post on Zulip Lee Surprenant (Nov 16 2020 at 17:04):

for 1, it must be ReferenceType/id (for relative references)

view this post on Zulip Lee Surprenant (Nov 16 2020 at 17:04):

for 2, you can omit the ReferenceType/ prefix if its unambiguous

view this post on Zulip Josh Mandel (Nov 16 2020 at 17:19):

for 2, you can omit the ReferenceType/ prefix if its unambiguous

(And as a side note, one way to make it unambiguous in a search is with a modifier -- e.g., Observation?subject:Patient=123. Though this particular example would be pretty unusual, since there's a dedicated patient= search parameter that accomplishes exactly this restriction out of the box.)

view this post on Zulip Paul Church (Nov 16 2020 at 17:21):

(it annoys the heck out of me that you can do subject:Patient=123 or subject=Patient/123 or patient=123 to solve the same problem)

view this post on Zulip Gino Canessa (Nov 16 2020 at 18:34):

We should probably just come up with a new unified syntax that can do it all!

view this post on Zulip Grahame Grieve (Nov 16 2020 at 21:22):

It's technically possible to put just a base string in the reference:

"patient" : { "reference" : "8cdf70c5-a3d0-4910-935d-d59594079647"} }

What this means is that the literal reference [base]/8cdf70c5-a3d0-4910-935d-d59594079647 resolves to something that is a valid resource type of the resources allowed in this context.

Obviously this means that the target resource is not being served up by a server that conforms to the RESTful API. And therefore it is indeterminate what it means for RESTful API search, since the RESTful search is search on the RESTful API.

view this post on Zulip Derek Ritz (Nov 16 2020 at 21:54):

I'm very sorry if the answer to this is obvious to everyone but me... but is this problem made worse by situations where there are multiple FHIR servers, each playing unique roles in an HIE architecture? For example... if there is a FHIR server acting as an EMPI and a separate one acting as a shared health record (SHR... or CDR), are we forced into needing to employ fully specified URLs? And if not, are relative references able to operate outside the scope of a single FHIR server?

view this post on Zulip Lloyd McKenzie (Nov 16 2020 at 21:56):

Relative references are limited to the scope of a single server (unless their served up by a facade that masks the existence of multiple back-end servers)

view this post on Zulip Lloyd McKenzie (Nov 16 2020 at 21:56):

That's the only way to ensure unique resolution

view this post on Zulip Grahame Grieve (Nov 16 2020 at 22:00):

are relative references able to operate outside the scope of a single FHIR server

The specification does not say that this is not possible. Note the double negative there, with care. There are immediately obvious challenges with doing this, but if the eco-system can ensure that each type has a master server, and this is fixed in advance, then it's possible. But that's super fragile; much much better to use absolute references

view this post on Zulip Derek Ritz (Nov 16 2020 at 22:03):

Thanks @Lloyd McKenzie and @Grahame Grieve. So... realistically... one would be well-served to always use absolute references as a matter of good practice. This way -- if separate servers needed to be lit up at a later date (to handle high traffic loads, for example) -- it'd all just keep working... right? And if relative references were used... perhaps not so much.

view this post on Zulip Grahame Grieve (Nov 16 2020 at 22:05):

maybe. depends on how it plays out. Typically, multiple servers = multiple IP address for the same name in DNS, and the scaling solution is opaque to clients. But if it's not... then maybe absolute references would have helped (retrospectively)

view this post on Zulip John Moehrke (Nov 16 2020 at 22:05):

my understanding is that relative references would be in the context of an obvious base.. the example given here is that they are used within a Bundle, so the base on the bundle gives context.
I don't think that one MUST use relative references inside a Bundle... right?

view this post on Zulip John Moehrke (Nov 16 2020 at 22:11):

thus a trusted intermediary (I) might assemble a Bundle made up of federated queries out to many (A, B, C, D) . Each of the federated queries would have had relative references to each Bundle response.. that trusted intermediary (I) might then create a Response Bundle of its-own (I:Bundle) expand all the relative references from the (A, B, C, D) bundles into full URL and assemble them all into the one Bundle owned by the trusted intermediary (I-Bundle). Given that this trusted intermediary didn't add any resources of its-own (not disallowed, just for example), then all the resources in the Bundle would not have relative References but have fully specified URL back to the federation of resource servers. The result would be clear and compliant. --- right?

view this post on Zulip Grahame Grieve (Nov 16 2020 at 22:15):

yes it could be done that way

view this post on Zulip Derek Ritz (Nov 16 2020 at 22:39):

@John Moehrke -- is that what a Document Registry actor might do (as defined in the IHE MHDS spec)? This seems to be very much the kind of trusted role the Interoperability Layer plays in an OpenHIE architecture and the kind of tasks it could be expected to perform.

view this post on Zulip John Moehrke (Nov 17 2020 at 14:05):

@Derek Ritz MHDS does not need to do this as the Document Registry is the owner of the DocumentReference, DocumentManifest, and List resources. Same is true of the other central FHIR services (PMIR, SVCM, ATNA, etc). This is just normal MHDS... But it might be a solution for a federation of MHDS(s)

view this post on Zulip Robin Arnold (Nov 18 2020 at 14:52):

@Grahame Grieve this is OK iff the id is unique across all resource types in a given context. But the spec states that: "The logical id is unique within the space of all resources of the same type on the same server." By inference, it does not need to be unique across resource types, which I think exposes the issue described in my original post. Because this relates to compartment membership, I believe this could lead to information leakage.

view this post on Zulip Grahame Grieve (Nov 18 2020 at 16:42):

I'm not sure what you mean. If you use a literal reference then that can only resolve to one address, and that can't be more than one thing

view this post on Zulip Yunwei Wang (Nov 18 2020 at 16:52):

@Robin Arnold According to https://build.fhir.org/references.html#literal "a relative URL, which is relative to the Service Base URL, or, if processing a resource from a bundle, which is relative to the base URL implied by the Bundle.entry.fullUrl (see Resolving References in Bundles)". I don't see, in your example, how you can use relative reference without resource type.

view this post on Zulip Robin Arnold (Nov 18 2020 at 16:59):

Consider this scenario. I create a resource "Patient/abc" and then "CareTeam/ct1" which includes a participant reference = "abc". This places "CareTeam/ct1" in the compartment of "Patient/abc".

Now let's add a new resource "RelatedPerson/abc" which has nothing to do with the above resources, other than it happens to share the same literal id. This is valid, because ids are only unique within a resource type. However, this causes our resource "CareTeam/ct1" to be included in the compartment of this new resource (based on participant reference = "abc" and according to the compartment definition for CareTeam).

view this post on Zulip Yunwei Wang (Nov 18 2020 at 17:31):

Here is problem. According to the spec, the relative url is based on "Service Base URL" (see the link in my previous post). So unless your patient can be accessed by [base]/abc, reference = abc is not correct.

view this post on Zulip Robin Arnold (Nov 18 2020 at 17:48):

@Yunwei Wang this is ideally what I'd like to have confirmed. I suspect I'm missing something implied by @Grahame Grieve in his earlier post: "It's technically possible to put just a base string in the reference: "patient" : { "reference" : "8cdf70c5-a3d0-4910-935d-d59594079647"} }".

view this post on Zulip Paul Church (Nov 18 2020 at 17:59):

My take on what Grahame said is that the spec allows that case, but unless your implementation serves up a resource at [base]/123, you are free to reject "reference":"123" because it can't refer to anything on your server.

view this post on Zulip Robin Arnold (Nov 18 2020 at 18:04):

Thanks @Paul Church very reasonable.

view this post on Zulip Yunwei Wang (Nov 18 2020 at 18:06):

Yes. That is my understanding too. If your server does serve Patient/123 at [base]/123, there is no problem for refernece = 123. But then you cannot claim that [base]/123 also serve as endpoint for RelatedPersion/123. The url serves one resource only.


Last updated: Apr 12 2022 at 19:14 UTC