FHIR Chat · How to handle multiple IG's on one server? · implementers

Stream: implementers

Topic: How to handle multiple IG's on one server?


view this post on Zulip Ryan Conley (Sep 30 2021 at 18:01):

More specifically, the question arises from what to do when one FHIR server implements multiple IG's, but these IG's have overlapping resources. Take the Da Vinci PDex IG and the CARIN BB IG for instance--both have a patient resource. How does a server handle being able to serve multiple patient resources?

My current solution is to use a base Patient FHIR resource as the source of truth for the patient resource. This means for instance that the fhirUser claim URL as specificed by the SMART spec will be a link to this base R4 patient resource. The base patient resource will then have links to a PDex patient and a CARIN BB patient via the link field.

At the last connectathon this was brought up as a major issue, where no one was aware of a standard or best practice for handling this expected use case. Some other options I heard were as follows:

  • Simply combine the profiles to make one super profile that is compliant with all the profiles (rejected because although there are no conflicts in the example I listed, there is nothing stopping different IG's from creating a profile on the same resource that would cause a conflict)
  • Don't have a base R4 resource (rejected because there is no obvious way as to what the entry point of the application should then be i.e. the fhirUser claim in the SMART token)

There were possibly others, but there is a lot of confusion around a topic that I feel should be explicitly called out in the FHIR specification somewhere considering the spec was designed with this in mind of a server being able to implement multiple IGs and the community at large being unsure as to how to handle this.

view this post on Zulip Michele Mottini (Sep 30 2021 at 18:05):

Combine the profiles. If they are incompatible then you'll need to have separate end points

view this post on Zulip Michele Mottini (Sep 30 2021 at 18:06):

(But PDex and Carin and US core etc profiles should be compatible - if they are not they should be fixed)

view this post on Zulip Lloyd McKenzie (Sep 30 2021 at 19:05):

In general, you serve up resources, not profiled instances. You simply work to ensure that the resources you serve up meet the requirements of all of the profiles you need to. (And monitor the creation of profiles to ensure they don't impose constraints that would prevent compliance with other profiles.)

view this post on Zulip Grahame Grieve (Sep 30 2021 at 19:30):

there's a tool that can be do the profile combining for you, to make it easy

view this post on Zulip Grahame Grieve (Sep 30 2021 at 19:30):

both from a reading and a writing perspective

view this post on Zulip Ryan Conley (Sep 30 2021 at 19:52):

@Michele Mottini @Lloyd McKenzie That's good to know, but is it not true that there is nothing stopping these independent IGs from creating conflicts with one another? Is this not a big enough concern? Is there any documentation or further discussion on this matter? (I didn't find anything else in Zulip.)

@Grahame Grieve If you know what it's called or where I should look for this tool it would be greatly appreciated.

view this post on Zulip Grahame Grieve (Sep 30 2021 at 19:54):

there's nothing stopping it, but we do have processes in place to make it less likely - it's not an outcome we're in favor of at all. And it's a valid criticism to make of the IGs that they don't allow combining like that. And in our experience, it's rare.

view this post on Zulip Paul Church (Sep 30 2021 at 19:55):

HL7 working groups should be voting down any IG that is so restrictive that it couldn't be compatible with other IGs. It shouldn't even be necessary for the group to understand all possible combinations - just avoid patterns that are likely to cause conflict.

view this post on Zulip Lloyd McKenzie (Sep 30 2021 at 19:55):

Nothing stops IGs from creating conflicts other than good design. It's possible that not all of your data will be valid against all profiles. For example, a profile on Patient might say that deceased[x] is prohibited - because deceased patients aren't allowed for that use. That doesn't mean that your system can't have patients where that element is true, only that they can't be used for the use-case the profile is designed for.

view this post on Zulip Grahame Grieve (Sep 30 2021 at 19:56):

as for the tool: https://confluence.hl7.org/display/FHIR/Using+the+FHIR+Validator#UsingtheFHIRValidator-ComparingImplementationGuides - but this is rather unuseful right now.

view this post on Zulip Lloyd McKenzie (Sep 30 2021 at 19:58):

More problematic is profiles that do things like say "Patient.name is 1..1" - i.e. patients aren't allowed to have multiple names. That's generally not a true statement, and the profile should instead say "There must be one slice of Patient.name that meets these narrow filter characteristics" (e.g. has a particular extension). That allows the system that wants only one name to find the one it needs without prohibiting all the others from being present.

view this post on Zulip Grahame Grieve (Sep 30 2021 at 20:33):

this is more useful: https://confluence.hl7.org/display/FHIR/Using+the+FHIR+Validator#UsingtheFHIRValidator-ComparingProfiles

view this post on Zulip René Spronk (Oct 01 2021 at 14:00):

If one stores the union of all profiles one needs to be able to communicate, you'll have to morph them into the appropriate profiled-resource before sending the resource. Given that in general it's not a good idea to store profile metadata in your persistence layer, this kind of approach may be a best practice anyway. You will encounter incompatible profile requirements - certainly if one were to be involved in any projects/product development that is to be used across jurisdictions/countries.

view this post on Zulip Lloyd McKenzie (Oct 02 2021 at 01:38):

I don't know that it's a given that profile requirements across differing jurisdictions/countries means it's a given that they must be non-compatible. If well designed, they shouldn't be non-compatible. It should ideally possible for a system to spit out prescriptions or vital signs that are just as valid in the US as Russia as Nigeria. The only possible issue might be language, and even there there are standard conventions for supporting multiple languages if your software has the capability of figuring out the translations.

view this post on Zulip René Spronk (Oct 02 2021 at 15:18):

Language, and terminologies, and the "terminfo" challenge, and more/less richness in terms of data. Besides, not all profiles will be 'well designed' ..

view this post on Zulip Lloyd McKenzie (Oct 02 2021 at 16:17):

Terminologies shouldn't prevent interoperability - simply send the codes required by all jurisdictions. (Well-designed profiles shouldn't ever mandate that only 'their' code is present.) Certainly it's true that not all profiles will be well-designed, but there's nothing that makes jurisdiction boundaries present that prevents following good design principles.

view this post on Zulip René Spronk (Oct 03 2021 at 07:36):

Should terminologies require a license (e.g. SNOMED), one may not be able to send "all codes". But in general you're correct that such an approach should work.

view this post on Zulip Lloyd McKenzie (Oct 03 2021 at 14:40):

There's a general expectation of putting a filter on your outbound content to strip off anything "this receiver isn't allowed to have". Terminology licensing considerations would need to be a part of this just as patient consent and other business rules would. (I wasn't aware of any SNOMED restriction that prohibits licensed senders from transmitting codes to non-licensed receivers, though there may be limitations on what licensed receivers can do. Obviously whether a sender counts as licensed or not may depend on where their system is installed.)

view this post on Zulip Jens Villadsen (Oct 18 2021 at 08:04):

Michele Mottini said:

Combine the profiles. If they are incompatible then you'll need to have separate end points

not necessarily - conflicting profiles are ok on the same endpoint. Its on the receiver side where you then have to filter it out on what is supported and what isn't supported

view this post on Zulip Lloyd McKenzie (Oct 18 2021 at 14:10):

If one profile says "must have no more than 1" and another profile says "must have at least 2", then the instances coming out of the endpoint can't comply with both.

view this post on Zulip Jens Villadsen (Oct 18 2021 at 19:08):

Right - reading might be necessary to handle on different endpoints - but writing in theory can be handled on the same endpoint.

view this post on Zulip Jose Costa Teixeira (Oct 18 2021 at 19:37):

Lloyd McKenzie said:

If one profile says "must have no more than 1" and another profile says "must have at least 2", then the instances coming out of the endpoint can't comply with both.

I don't know if I'm getting this right, but I pretty much expect the same endpoint to support several profiles for one same resource

view this post on Zulip Jose Costa Teixeira (Oct 18 2021 at 19:38):

A medication system may have MedRequests for prescriptions and for instance-orders, for example.

view this post on Zulip Daniel Venton (Oct 18 2021 at 19:48):

No two IGs should be mutually exclusive. They should be worded, may have 1 with this condition (slice) but allow others. Must have 2 with this condition (slices) but allows more. If you find 2 IGs that are mutually exclusive it should be brought to the authors attention so it can be addressed.

view this post on Zulip Jose Costa Teixeira (Oct 18 2021 at 19:55):

Daniel Venton said:

No two IGs should be mutually exclusive. They should be worded, may have 1 with this condition (slice) but allow others. Must have 2 with this condition (slices) but allows more. If you find 2 IGs that are mutually exclusive it should be brought to the authors attention so it can be addressed.

I don't understand this.
If one IG says "this MedRequest resource SHALL have intent=X, no other allowed"
and another says "this MedRequest resource SHALL have intent=Y, no other allowed"
they can still work together, right?

view this post on Zulip Daniel Venton (Oct 18 2021 at 20:05):

What that means is that only intent=X MedRequests are considered part of the profile. It doesn't mean that all MedRequests on the server are intent=X. You just don't return intent<>X when you know that they want resources that conform to that profile.

view this post on Zulip John Moehrke (Oct 18 2021 at 20:12):

agree, but even that level of filtering is not implied by a server saying it is conformant to both IGs.

view this post on Zulip John Moehrke (Oct 18 2021 at 20:12):

one resource can't be compliant with both profiles. but the server can certainly support both profiles.

view this post on Zulip Jose Costa Teixeira (Oct 18 2021 at 20:25):

@Daniel Venton I don't know if that conflicts with what I meant. I want the same server to support both intent=X and intent=Y

view this post on Zulip John Moehrke (Oct 18 2021 at 20:33):

so what do you mean by "support"? I think that is the problematic word. It is not defined, and when "support" is not defined it can take on the definition of "support" related to dangling-from-a-rope-tied-around-ones-neck.

view this post on Zulip Daniel Venton (Oct 18 2021 at 20:49):

I believe this is where _profile filter comes into play. /Resource?_profile=IntentXProfile vs _profile=IntentYProfile. As a server you could implement the request of "I want all resources that conform to IntentXProfile" by SELECT * WHERE Intent=X. This allows you to have all the data, regardless of profile and only return the subset that matches the profiles requested.

view this post on Zulip Jose Costa Teixeira (Oct 18 2021 at 21:05):

John Moehrke said:

so what do you mean by "support"? I think that is the problematic word. It is not defined, and when "support" is not defined it can take on the definition of "support" related to dangling-from-a-rope-tied-around-ones-neck.

Well, "support" as "carry" or "hold" - being able to hold both types of resources.

view this post on Zulip Jose Costa Teixeira (Oct 18 2021 at 21:07):

dangling from a rope seems a distant declination from the word "support"

view this post on Zulip Jose Costa Teixeira (Oct 18 2021 at 21:08):

Daniel Venton said:

I believe this is where _profile filter comes into play. /Resource?_profile=IntentXProfile vs _profile=IntentYProfile. As a server you could implement the request of "I want all resources that conform to IntentXProfile" by SELECT * WHERE Intent=X. This allows you to have all the data, regardless of profile and only return the subset that matches the profiles requested.

We can use it like that, or we can search ?intent=X

view this post on Zulip Michele Mottini (Oct 18 2021 at 21:43):

You can support multiple profiles if _different_ instances of the resource matches different profiles (as in the MedicationRequest.intent example) but if one Immunization profile says that protocolApplied is 1..1 and another Immunization profile says that protocolApplied is 0..0 then the same end point cannot support both

view this post on Zulip Jose Costa Teixeira (Oct 19 2021 at 05:52):

Why is that?

view this post on Zulip Jose Costa Teixeira (Oct 19 2021 at 05:53):

Can we not post one of each, provided we declare the profile?

view this post on Zulip Frank Oemig (Oct 19 2021 at 11:46):

The problem is that a server stores the instance. And if conflicting profiles enforce different details than there must be some kind of translation...

view this post on Zulip Jens Villadsen (Oct 19 2021 at 12:12):

@Jose Costa Teixeira if the profiles are mutually exclusive your instance cannot conform to both. If the profiles are NOT mutually exclusive, then the sender can submit an instance, an the receiver can (if it wants to, at its own expense) mark up the instance with all the profiles it knows to the degree that in finds it beneficial that the instance conforms to.

view this post on Zulip Daniel Venton (Oct 19 2021 at 12:12):

It is my belief that there should only ever be 1 instance of any resource and it should have 100% of the data that corresponds to it.
In the example of IGa says SHALL NOT have protocolApplied and IGb says SHALL have protocolApplied then the IG authors should come together to resolve.
OR perhaps you use the _profile filter again Immunization?_profile=IGa means "SELECT * FROM Immunization where protocolApplied is null"
You have all the data, you can comply with IGa by returning just those that do not have protocolApplied.
Maybe in some alternate reality you strip protocolApplied from the resource on the way out the door JIT, but I don't imagine that is legally, clinically sound. As in what if you strip off a piece of information that changes treatment for the worse, I think you'd be liable for the harm.

If a user does Immunization?all and then they complain "You gave me resources that don't comply with IGa" you get to say, you didn't ask for only resources that apply to IGa you asked for all.
Or perhaps they say, "This resource doesn't comply with IGa." As long as you don't declare that it does, then what's the harm. What makes it comply with IGa (not having protocolApplied) thusly any resource that does have protocolApplied isn't part of that IG.

view this post on Zulip Jens Villadsen (Oct 19 2021 at 12:16):

Daniel Venton said:

... In the example of IGa says SHALL NOT have protocolApplied and IGb says SHALL have protocolApplied then the IG authors should come together to resolve.

I disagree. That would require world global harmonization on ALL levels. The author of IG's cannot take all other IG's into account, and probably shouldn't.

view this post on Zulip Daniel Venton (Oct 19 2021 at 12:39):

I'm pretty sure that @Lloyd McKenzie mentioned that IGs shouldn't be written a mutually exclusive manner, but I'll leave that to the wayside.

The point is, you still store all the data. If a user requests data that matches IGa then only return the resources that match IGa. If the user requests data that matches IGb only return resources that match. You can have them all, just filter based on the requested profile. IGa doesn't tell you that your database can only have conformant resources, it says only resources that meet certain conditions are conformant with this profile. All other resources are allowed to exist.

view this post on Zulip Lloyd McKenzie (Oct 19 2021 at 13:24):

I agree with @Daniel Venton in terms of best practice. However, sometimes reality intervenes. Some receivers have a legitimate legal requirement to never receive data they don't recognize. (Some receivers may think they have that need, but in fact don't...) Also, some interfaces only want a subset of data - e.g. only active living patients. That doesn't mean that others can't exist, just that certain operations or whatever need to be filtered.

view this post on Zulip Michele Mottini (Oct 19 2021 at 13:52):

(My example is a real case: https://worldhealthorganization.github.io/ddcc/StructureDefinition-DDCCImmunization.html, http://hl7.org/fhir/uv/shc-vaccination/2021Sep/StructureDefinition-shc-vaccination-ad.html#tab-diff)

view this post on Zulip Michele Mottini (Oct 19 2021 at 13:54):

You cannot 'POST both version' because systems in general do not store FHIR - they have some database that contains an immunization record, and then they render it as FHIR - and they cannot really render it both ways out of the same end point

view this post on Zulip Jose Costa Teixeira (Oct 19 2021 at 16:17):

What about my case where I want a medication system to hold both prescriptions and instance orders (both flavors of MedRequest)?

view this post on Zulip Jens Villadsen (Oct 19 2021 at 17:27):

@Jose Costa Teixeira is it a case where the profiles conflict?

view this post on Zulip Jose Costa Teixeira (Oct 19 2021 at 17:32):

Those 2 flavors have different fixed code for MedRequest.intent

view this post on Zulip Jens Villadsen (Oct 19 2021 at 17:34):

well - then your instance can only conform to one of the profiles

view this post on Zulip Jose Costa Teixeira (Oct 19 2021 at 18:47):

I thought this was about the server supporting the 2 profiles or not. as long as that's possible, I'm not worried. Of course my instances will not claim compatibility with incompatible profiles.

view this post on Zulip Jose Costa Teixeira (Oct 19 2021 at 18:47):

Thanks

view this post on Zulip Michele Mottini (Oct 19 2021 at 18:50):

What about my case where I want a medication system to hold both prescriptions and instance orders

That is OK because those are separate things (if I understand correctly) - the server holds both and renders them according to the two profiles

view this post on Zulip Jose Costa Teixeira (Oct 19 2021 at 18:59):

The server doesn't render. The server serves, right?

view this post on Zulip Grahame Grieve (Oct 19 2021 at 18:59):

there's a language problem here- a single server can host conflicting profiles, but only if the data and the usage is compartmented logically - somehow - so that the conflicting data is a requirement. An underlying issue here is the difference between system-ish profiles and data-ish profiles. The spec describes them as entirely different, and they are in principle, but they tend to leak into each other in practice

view this post on Zulip Rik Smithies (Oct 19 2021 at 19:08):

Agree re language - "supports" may be thought to imply disallowing other instances. If you "support" X then can you allow a Y that doesn't conform to X? The words "hosts" or "serves" seem more open.

view this post on Zulip Michele Mottini (Oct 19 2021 at 20:09):

The server doesn't render. The server serves, right?

Servers render the data they have as FHIR

view this post on Zulip Daniel Venton (Oct 19 2021 at 20:11):

Is there an expectation that if a server can serve resources that comply to a specific IG, that all resources served by the server comply with the specific IG?

view this post on Zulip Lloyd McKenzie (Oct 19 2021 at 20:15):

It probably depends on the IG...

view this post on Zulip Daniel Venton (Oct 19 2021 at 20:29):

If true, that all resources served by a server comply with a profile. You can still have 1 database with all data. But instead of doing the filter via the _profile parameter you implement the filter by the domain name:
IGa.myfhirserver.com/Resource = returns (SELECT * FROM MyDb WHERE IGa compliant)
IGb.myfhirserver.com/Resource = returns (SELECT * FROM MyDb WHERE IGb compliant)

view this post on Zulip Grahame Grieve (Oct 19 2021 at 21:07):

so it all depends on the nature of the profiles. Obviously with observations, there'll be multiple applicable profiles that observations conform to and anything more sophisticated than a $10 device will have different kinds of observations. Where as system level profiles - it's hard to have more than one.

The example of observations is pertinent - you do a search for observations for a patient, obviously you're going to get lots of different kinds of observations, and those observations will conform to lots of different profiles (mostly, not explicitly). But you search for all observations with a particular code... they're probably all going to conform to a single profile, but even then, there could be some observations that conform to some profiles, and some that conform to others

Kinds of profiles on Observations:

  • jurisdictional polices about coding
  • system policies about provenance/authorship etc
  • domain policies about observation codes and components and units and reference ranges
  • institutional policies about annotations and workflow rules
  • etc

The problem is that IGs don't provide a computable way to understand all this.

view this post on Zulip John Moehrke (Oct 20 2021 at 20:59):

Postel's Law


Last updated: Apr 12 2022 at 19:14 UTC