FHIR Chat · Facade for multiple backends · implementers

Stream: implementers

Topic: Facade for multiple backends


view this post on Zulip Alexander Henket (Nov 22 2017 at 12:04):

Suppose I have a facade/gateway FHIR server that serves multiple backends. Suppose I sometimes want to get data from "all" systems, and sometimes want to get data from "a specific system".

In our case we would have a facade on our national spine serving FHIR for thousands of systems. The normal current setup for query would be that you ask for e.g. MedicationDispense irrespective of where the data comes from and the national spine would look up where data is and return data from all relevant places. However we also want to support MedicationDispense specifically from systemA.

We see two options:

  • RESTful: [base]/systemA/...
  • Query parameter: [base]/...?_endpoint=systemA

Anybody else looked at this and how did you solve that?

@reli, @Tom de Jong, @Christiaan Knaap

view this post on Zulip Christiaan Knaap (Nov 22 2017 at 12:07):

Certainly did not solve it already. Both approaches will require some custom handling as it is not defined in FHIR itself. As for Vonk, Query parameter is a bit better fit to Vonk's programming model.
A thorough approach might be using Provenance for this.

view this post on Zulip Theo Stolker (Nov 22 2017 at 12:40):

Hi @Alexander Henket ,

One part I do not see addressed in your question, but I believe you have to do for the cross-system query is make sure that every resource returned is decorated with a tag that indicates from which system the resource was returned.

Once you have done that, I think the logical solution would be to query for the system specific tag (or tags) when you want to filter data from a subset of systems.

view this post on Zulip Theo Stolker (Nov 22 2017 at 12:44):

Oh, and just to be sure, if you define your own query parameters, make sure these do not start with an underscore, that is reserved for system parameters!

view this post on Zulip Alexander Henket (Nov 22 2017 at 13:12):

I think I quite like the elegance of querying for a tag. Would that be something for Vonk too @Christiaan Knaap ?

view this post on Zulip Grahame Grieve (Nov 22 2017 at 14:19):

this would be another use for Resource.meta.source (which I proposed in a different topic here, which would be a url)

view this post on Zulip Brian Postlethwaite (Nov 22 2017 at 21:45):

(which is also not in the current builds right?)

view this post on Zulip Brian Postlethwaite (Nov 22 2017 at 21:46):

I'm also considering implementing this, which in my case is a federator.

view this post on Zulip Grahame Grieve (Nov 22 2017 at 23:32):

yes not in current build

view this post on Zulip Alexander Henket (Nov 23 2017 at 09:11):

Does that work for push too? I.e. could I POST something to a specific backend the same way?

view this post on Zulip Christiaan Knaap (Nov 23 2017 at 09:23):

The standard Vonk server does not behave this way, but I think the architecture makes this very well possible. 'Federation' - on the todo list :-)

view this post on Zulip Grahame Grieve (Nov 23 2017 at 09:29):

you could make it so. Server decision.

view this post on Zulip Grahame Grieve (Nov 23 2017 at 09:29):

I added Resource.meta.source to R4 so people can look see, btw

view this post on Zulip Alexander Henket (Nov 23 2017 at 09:57):

For push: would you not need Resource.meta.target (too)

view this post on Zulip Alexander Henket (Nov 23 2017 at 09:58):

How would Resource.meta.source|target stack up against FHIR Messaging? If you do FHIR Messaging: do you still need Resource.meta.source|target?

view this post on Zulip Grahame Grieve (Nov 23 2017 at 09:59):

target is wrong. that's a messaging view; set it to source to say what it will be

view this post on Zulip Alexander Henket (Nov 23 2017 at 11:01):

So source behaves as "targetSource" then. I get it now you explained it, but be prepared to explain this over and over again. When I push something to a specific system, then for all sense and purposes that is form of messaging, regardless of it being RESTful or FHIR Messaging.
Normally the endpoint is enough as target system. With a gateway/facade it might not be. Calling that target system "source" feels counter intuitive

view this post on Zulip Grahame Grieve (Nov 23 2017 at 11:02):

well, messaging and rest are not the same, and this is one area of difference. In a message, if you wanted to specify a target, you'd use Bundle.entry.link

view this post on Zulip Alexander Henket (Nov 23 2017 at 11:38):

That works if it is a Bundle you are sending

view this post on Zulip Alexander Henket (Nov 23 2017 at 11:42):

But more importantly: some unification in how to handle this would be nice. So if the Resource.meta.source is "the thing", then I would not use Bundle.entry.link anymore, but the Bundle.meta.source or Bundle.entry.Resource.meta.source. (the last one only if I somehow try to upload a Bundle where different entries target different systems, but that sounds really funky)

view this post on Zulip Alexander Henket (Nov 23 2017 at 11:46):

In looking at http://build.fhir.org/resource-definitions.html#Meta.source it currently does not feel suited for use when I want to say "Hey gateway, please hand this resource to system X".

Current wording
Identifies the system that is the source of the information in this resource.

When I push something, it feels like the way to tell the other end something about me as sender.

view this post on Zulip Grahame Grieve (Nov 23 2017 at 12:05):

in messaging, you will have a bundle, and you should still use Bundle.entry.link.

view this post on Zulip Grahame Grieve (Nov 23 2017 at 12:06):

in REST, you are telling the server to 'make it so' - and so when it makes the source so, it talks to the system you identify as the source

view this post on Zulip Alexander Henket (Nov 23 2017 at 12:07):

For the record: we're doing RESTful, not Messaging.

view this post on Zulip Alexander Henket (Nov 23 2017 at 12:08):

The behavior of POST-ing a Bundle to an endpoint with meta.source, telling the server "make it so" identifying the meta.source as intended target, just is not something I can wrap my head around

view this post on Zulip Alexander Henket (Nov 23 2017 at 12:08):

Could be my limitation

view this post on Zulip Alexander Henket (Nov 23 2017 at 12:14):

Trying again.

Use case 1: I want to query a specific endpoint 903 through an intermediary gateway

GET [base]/Condition?_tag=http://aorta-zorg.nl/apps|903

Use case 2: I want to push contents to a specific endpoint 903 through an intermediary gateway

POST [base]/Condition?_tag=http://aorta-zorg.nl/apps|903

Use case 1 would not have an HTTP body. Use case 2 would have an HTTP body where the *.meta.source would be my system. The reason for that is that my system might also be behind a gateway for multiple systems making it less obvious which system is pushing data.

view this post on Zulip Grahame Grieve (Nov 23 2017 at 20:38):

so the second is not valid following the spec. but as I say, if you were using source:

GET [base]/Condition?_source=http://aorta-zorg.nl/apps/903

POST [base]/Condition

<[Resource]>
  <meta>
    <source value="http://aorta-zorg.nl/apps/903"/>
  </meta>
</[Resource]>

view this post on Zulip Grahame Grieve (Nov 23 2017 at 20:39):

the second is saying: set the state of this new resource as if source was http://aorta-zorg.nl/apps/903. The server makes it so - which in this case, means, posting it through to the http://aorta-zorg.nl/apps/903 server

view this post on Zulip Alexander Henket (Nov 23 2017 at 20:51):

How would I then tell the target system that some of my contents came from source A and others from source B if the meta.source cannot be used for that because it is repurposed to mean target?

view this post on Zulip Grahame Grieve (Nov 23 2017 at 20:56):

it's not repurposed. If you've moved the goal posts to mean that some of the content of a resource comes from one server, and some from another, and the client needs to know about the derivation, then I don't think there's a solution in RESTful for you. And it sounds like a bad idea

view this post on Zulip Alexander Henket (Nov 23 2017 at 20:56):

Provenance?

view this post on Zulip Grahame Grieve (Nov 23 2017 at 20:57):

maybe. for reads. Sounds like a really difficult thing for post. though it's just going to be difficult anyway.

view this post on Zulip Alexander Henket (Nov 23 2017 at 20:58):

Use case 1: I want to query a specific endpoint 903 through an intermediary gateway

GET [base]/Condition?_source=http://aorta-zorg.nl/apps/903

Use case 2: I want to push contents to a specific endpoint 903 through an intermediary gateway

POST [base]/Condition

<[Resource]>
  <meta>
    <source value="http://aorta-zorg.nl/apps/903"/>
  </meta>
</[Resource]>

@Theo Stolker, @reli, @Christiaan Knaap, @Tom de Jong Thoughts? Objections? Support? Since we need it in STU3 we probably need a tag for it, but that can be arranged

view this post on Zulip Brian Postlethwaite (Nov 24 2017 at 00:52):

The source to me has nothing to do with messaging, its about where the original content came from (very useful in curated or federated content)
Its not asking it to go somewhere, its a little on its heritage (and the provenance will have the full detail) I'd like to see this as multi-cardinality if there were multiple contributors to the content. Just a thought though.

view this post on Zulip Grahame Grieve (Nov 24 2017 at 01:12):

I deliberately made it singular, even though a resource might have multiple sources, because there's real complexity there

view this post on Zulip Brian Postlethwaite (Nov 24 2017 at 01:18):

Great, thanks.

view this post on Zulip René Spronk (Nov 24 2017 at 05:45):

How does this tie in with a metadata registry (a record locator) like the Dutch LSP or IHE XDS ? I'd like to see seamless integration with those in case we need to do GET [base]/Bundle/[x]?_source=yyyyyyyyyy or GET [base]/Binary/[x]?_source=yyyyyyy. Normally I'd expect the record locator to work out where something is (and hide it from me when GETting), but there may be use cases where one wishes to explicitly request a specific application.

And you'd better use Provenance when doing POST in this context (i.e. always post a Bundle inclusive of Provenances), otherwise one will have no clue as to who was responsible for the posted content. Create Graphdefinition that states that each posted resource SHALL have an associated Provenance resource.

view this post on Zulip Alexander Henket (Nov 24 2017 at 12:40):

René this whole thing is exactly about the LSP/AORTA and the FHIR Facade that will be in front of thousands of systems and potentially all XDS regions too. The usual query on the LSP/AORTA does not have any target system: the LSP figures out where stuff is and queries them all on your behalf and finally Bundles it all up in 1 single Response Bundle to you. The Bundle contains enough information to determine which information came from which system (all in V3).

Translating that to FHIR could amount to a Bundle of Bundles where each sub-Bundle is marked with meta.source and/or Provenance. We could use Provenance too to carry the V3 payload at least for debugging scenarios.

The reason I'm asking is because in the MedMij PHR scenarios we anticipate PHRs will want to target specific systems for a query after receiving a notification for a running subscription. Also PHRs will want to push observations from devices to specific systems. Hence use case 1 and 2

GraphDefinition is something someone once asked us about and I've not looked at that yet. I doubt many people will know what to do with it, but I might be wrong.

Grahame/Brian, if meta.source sometimes is "the source", and sometimes is "the intended future source" (aka "target" in my vocabulary), it is not going to work for me. It should be the one or the other.

view this post on Zulip Alexander Henket (Nov 24 2017 at 12:51):

The source to me has nothing to do with messaging, its about where the original content came from (very useful in curated or federated content)
Its not asking it to go somewhere, its a little on its heritage (and the provenance will have the full detail)

Fully agree. meta.source is about origin. Grahame however extended that notion to include additional semantics upon posting data. In posting data, now the meta.source means "please make it so that the source is X". This is not what I want to accomplish. I want my data to be routed to a particular system that is behind the facade that is my initial endpoint.

Maybe compare my situation with Aegis Touchstone: unless I send an HTTP header carrying my organizational/personal (API) key, the system will not know what party is testing and will not know how to route the incoming data.

view this post on Zulip Brian Postlethwaite (Nov 24 2017 at 12:52):

I would have never expected the source to be a target. To me this property should be for where the content came from. anything further should be in provenance.

view this post on Zulip Alexander Henket (Nov 24 2017 at 12:55):

Ok so this

GET [base]/Condition?_source=http://aorta-zorg.nl/apps/903

Only works if the only system serving Conditions from source 903 is in fact system 903 itself. Suppose a second system would be serving data from 903 we would be getting multiple responses. This is not allowed on the LSP/AORTA. Thusfar you may only serve contents that you are owner of

view this post on Zulip Alexander Henket (Nov 24 2017 at 12:57):

Nonetheless it seems that source is not our thing then and we're better off creating a custom meta.tag for it. All still assuming that using a tag could work for Vonk (@Christiaan Knaap ), HAPI-FHIR (@James Agnew) and other facades as a means to address a system behind the facade.

An alternative is something along the lines of the facade hosting endpoints per backend system, and a public/generic endpoint. So

GET https://aorta-zorg.nl/allapps/fhir/3.0.1/
GET https://aorta-zorg.nl/app/903/fhir/3.0.1/
GET https://aorta-zorg.nl/app/904/fhir/3.0.1/
GET https://aorta-zorg.nl/app/904/fhir/4.0.0/

You would host thousands of endpoints like that.

view this post on Zulip Theo Stolker (Nov 24 2017 at 14:24):

@Alexander Henket , looks great, I'll support this! And I meant that on your earlier post about the use of meta.source :)

view this post on Zulip Grahame Grieve (Nov 24 2017 at 14:34):

you're just not doing RESTful stuff when you describe it this way, and so you're finding that the RESTful interface can't do this. I'm not finding that surprising

view this post on Zulip Grahame Grieve (Nov 24 2017 at 14:35):

"Grahame/Brian, if meta.source sometimes is "the source", and sometimes is "the intended future source" (aka "target" in my vocabulary), it is not going to work for me. It should be the one or the other." - but no, you're misunderstanding. It's always the source. But when you put the resource to the server, you are asserting that in it's new state, this is now the source.

view this post on Zulip Lloyd McKenzie (Nov 24 2017 at 14:37):

I.e. In the old version of the Patient instance, demographics came from system X, but I've updated the instance so the demographics now come from system Y which I believe to be more authoritative.

view this post on Zulip Alexander Henket (Nov 25 2017 at 21:28):

I totally get how you intended it Grahame/Lloyd. I just don't agree with the idea. I was not at the point where we had a solution. I was at a point where we were looking for one. Turns out the problem is lesser known territory than I thought I would be.

Being purely RESTful would mean those thousands of endpoints. That way it is as if I'm talking to the system itself even if it is a facade serving for those thousands of systems. Works for both push and pull.

We however thought that would be unpractical. Secondly most queries would probably still go to the generic endpoint targeting all systems and then the response would need markers to indicate source. For that purpose, the meta.source just might be a reasonable thing, but since we might use Provenance for more details anyway, the meta.source then seems redundant.

Still hoping to hear from @Christiaan Knaap about what seems reasonable for Vonk considering I understand Vonk is a likely candidate to be the facade we're discussing.

view this post on Zulip Lloyd McKenzie (Nov 25 2017 at 22:33):

What about the idea do you disagree with? Even if we don't have "source", each version of a resource can have a distinct source from a Provenance perspective. Source can't really disagree with Provenance.

view this post on Zulip Alexander Henket (Nov 26 2017 at 09:22):

I think source should be just source, or as Brian put it origin. When you offer data to a server you are telling the server where it came from, not where you want that data to to come from in the future.

I can understand how you would like the result of your upload to be that some receiving system needs to be the new authorative source after processing what you have sent. But that is about the intention of your upload, not about origin at time of upload. The intention of your upload (just store, act on the data, accept you are now the new source of the data) is what messaging is about, the dynamic model if you will. Meta.source does not do for that purpose.

You are right that Provenance and meta.source bear overlap, which is why said that when you have Provenance which carries much more information, the meta.source seems redundant.

view this post on Zulip Lloyd McKenzie (Nov 26 2017 at 20:45):

Ok - that's my understanding of how "source" would work - it mirror's provenance. It tells the source of a create or update. It has nothing to do at all with where the data will be stored. There's no mechanism in FHIR to direct data to a specific storage location beyond the URL you POST/PUT to.

view this post on Zulip Lloyd McKenzie (Nov 26 2017 at 20:45):

The primary use-case for meta.source is so you don't have to retrieve a copy of the provenance to know where the data came from.

view this post on Zulip Brian Postlethwaite (Nov 26 2017 at 22:39):

And likely to know that there is a provenance of significance.

view this post on Zulip Grahame Grieve (Nov 26 2017 at 22:44):

well, there's multiple reasons why you could populate source but not create a provenance

view this post on Zulip Alexander Henket (Nov 27 2017 at 06:48):

I'm looking for a solution to address a system behind a facade in a RESTful way. I'm aware that what I ask has not been done before, but it is not possible that the problem didn't exist yet: Vonk and HAPI are or will be used in front of many systems.

Grahame told me meta.source exists as-of R4, but meta.source does not have the semantics I'm looking for. That doesn't make meta.source the solution, but it doesn't make the problem go away either.

So maybe a step back: do we at least share the idea that the problem as stated is relevant to solve?

view this post on Zulip Grahame Grieve (Nov 27 2017 at 07:30):

you can't ask for a RESTful solution, and then reject a RESTful solution. What are you looking for here? Do you really want a single RESTful facade to a bunch of servers such that the client doesn't need to worry about the bunch of servers in the background?

view this post on Zulip Jens Villadsen (Nov 27 2017 at 10:28):

won't we all :D

view this post on Zulip Lloyd McKenzie (Nov 27 2017 at 14:32):

Let me see if I can summarize your issue - you don't really want a "facade" - as the client will know - must know in fact - that there are multiple servers. But the client won't know the address of any of those servers. Instead they talk to a single aggregating endpoint and POST to that endpoint but somehow communicate to the endpoint what server they want the result sent to. Is that accurate @Alexander Henket?

view this post on Zulip Christiaan Knaap (Nov 29 2017 at 08:37):

Sorry for the delay. Discussed it a bit with @Vadim Peretokin as well.
The easiest solution in our opinion is to design a custom search parameter for this, probably on Resource (let's say 'fromsource').
After that in the Facade implementation you can handle this parameter by limiting the queries to the backend systems to just that source.
It would then - with a little extra work - even be possible to extract this searchparameter from the path as you suggested above, but it may be easier for clients to just add the searchparameter (&fromsource=903).

view this post on Zulip René Spronk (Nov 29 2017 at 15:22):

Reminds of me of a v3 discussion around messaging, one that we never managed to wrap up because consensus could simply not be reached. Trying to influence the delivery of messages beyond the designated end-point (here: the Facade) leads to lots of issues.

Anyways: I can see the use case for wishing a subset of systems (perhaps only 1) instead of asking the Facade to forward the query to all. But in terms of addressing I would not want to use a system URL, but an organization Id or even a healthcare Practitioner Id. They may move their data from one repository to another one, the author stays the same. Kind of a GET [base]Condition?_has:Provenance:agent.identifier=903 (that's probably not valid, but you get the idea). The Facade has to be smart enough to resolve that 'agent.identifier' into a URL (or a set of URLs in case that agent uses multiple repositories).

view this post on Zulip Grahame Grieve (Nov 29 2017 at 15:25):

I think it's wrong to claim that it's a 'facade' if the client has to know anything about it

view this post on Zulip Grahame Grieve (Nov 29 2017 at 15:25):

if the client has to know about it, I think 'agent' is the right word

view this post on Zulip Alexander Henket (Nov 29 2017 at 18:56):

Yes that’s accurate Lloyd

After some back n forth we’ll go with a url based solution for the first test drive and decide from there if we need something different. The url will be something like

https://aorta-zorg.nl/fhir/[fhirVersion]/apps/[appId]

This is fully RESTful and is comparable to a 1-to-1 facade/system solution.

Since the URLs are all registered in the national system/endpoint registry the discovery is no biggie.

view this post on Zulip Alexander Henket (Nov 29 2017 at 19:02):

The question to find the right endpoint is “get me endpoints for organization X that support application role Y”. As we have application role based certification in place for systems for them to be recognized on the network that will work. Questions like “what’s the uri for getting the medication from my pharmacy” could be answered with https://aorta-zorg.nl/fhir/3.0.1/apps/903/.

view this post on Zulip Alexander Henket (Nov 29 2017 at 19:05):

Grahame: maybe the word facade isn’t entirely accurate but it’s close enough I think. It’s a FHIR entrance to a non-FHIR network of servers

view this post on Zulip Alexander Henket (Nov 29 2017 at 19:09):

René/Vadim/Christiaan: a query param based solution is still on the table, but we had to make an initial decision before December 1 to start trialing with and landed on url. We’ll know within 7 months what the final answer will be during the big test drive of it all

view this post on Zulip Alexander Henket (Nov 29 2017 at 19:14):

Thanks all for your valuable input. I’ll post updates on the experience, good or bad, here for those interested

view this post on Zulip John Moehrke (Nov 29 2017 at 20:03):

Intermediary

view this post on Zulip John Moehrke (Nov 29 2017 at 20:04):

Conductor

view this post on Zulip Brian Postlethwaite (Nov 30 2017 at 20:58):

Intermediary I'd go for.
For me the facade hides all the details of operation behind it.

view this post on Zulip Mattias Flodin (Dec 05 2017 at 16:20):

@Alexander Henket I should add that we're doing pretty much the same thing, IIUC: using a FHIR API as frontend for multiple backing systems. In our case, each system has what we call a facade that sits between the frontend and the non-FHIR system.

view this post on Zulip Mattias Flodin (Dec 05 2017 at 16:21):

Though we envision some future systems will implement the FHIR API directly and can be used without a facade.

view this post on Zulip Alexander Henket (Dec 05 2017 at 16:26):

Good to know thanks @Mattias Flodin
@Brian Postlethwaite I would say that the url thing actually gives every backend system its own ‘front door’. So every front door then qualifies as facade while the whole ‘house with all front doors’ or ‘host of facades’ might go by a different name conceptually.

view this post on Zulip Mattias Flodin (Dec 05 2017 at 16:30):

We call that the service platform. It also contains a messaging system outside of the FHIR scope, that allows systems to broadcast events to other systems.

view this post on Zulip Grahame Grieve (Dec 05 2017 at 19:00):

at the Australian connectathon yesterday we were using the term 'federation'

view this post on Zulip Brian Postlethwaite (Dec 07 2017 at 08:35):

And I implemented a simple POC to cover some of the issues that may satisfy the needs in the specific context. It's only a partial implementation, but does show some useful stuff
https://github.com/brianpos/FhirFederation

view this post on Zulip Johan Eltes (Dec 13 2017 at 14:46):

René this whole thing is exactly about the LSP/AORTA and the FHIR Facade that will be in front of thousands of systems and potentially all XDS regions too. The usual query on the LSP/AORTA does not have any target system: the LSP figures out where stuff is and queries them all on your behalf and finally Bundles it all up in 1 single Response Bundle to you. The Bundle contains enough information to determine which information came from which system (all in V3).

Translating that to FHIR could amount to a Bundle of Bundles where each sub-Bundle is marked with meta.source and/or Provenance. We could use Provenance too to carry the V3 payload at least for debugging scenarios.

The reason I'm asking is because in the MedMij PHR scenarios we anticipate PHRs will want to target specific systems for a query after receiving a notification for a running subscription. Also PHRs will want to push observations from devices to specific systems. Hence use case 1 and 2

GraphDefinition is something someone once asked us about and I've not looked at that yet. I doubt many people will know what to do with it, but I might be wrong.

Grahame/Brian, if meta.source sometimes is "the source", and sometimes is "the intended future source" (aka "target" in my vocabulary), it is not going to work for me. It should be the one or the other.

Interesting. It seems we (Sweden) and Netherlands have the same national HIE architecture. We are however - not yet into FHIR, but are shaping up our plans. In management- and professional settings, we sometimes use the term "Virtual EHR" to label our concept of federation. It also reflects that we do not open up for end-to-end coupling by requiring clients to know / create dependencies to the system topology behind the "facade". We also have the exception of using "source system targeting" when responding to record locator event subscriptions. Since the event betrays the source of the event. We don't have XDE in the picture, though. Would be interesting to meet and share thoughts and strategies for national FHIR migration.

view this post on Zulip Michael Lawley (Dec 20 2017 at 00:21):

@Brian Postlethwaite 404 on https://github.com/brianpos/FhirFederation - think you meant https://github.com/brianpos/FhirFederator

view this post on Zulip Michael Lawley (Dec 20 2017 at 00:24):

This feature: Aggregated CapabilityStatement seems to me to be particularly tricky; how do you merge them?

view this post on Zulip Brian Postlethwaite (Dec 20 2017 at 00:35):

Yes, that's right, thanks @Michael Lawley

view this post on Zulip Brian Postlethwaite (Dec 20 2017 at 04:35):

That aggregated CapabilityStatement is a work in progress.
Its using the first as a template, then grafting in the others with an extension to indicate which services support which bits.
(need to do that for the search params too)


Last updated: Apr 12 2022 at 19:14 UTC