FHIR Chat · How to flatten References? · implementers

Stream: implementers

Topic: How to flatten References?


view this post on Zulip Abbie Watson (Dec 11 2016 at 20:50):

Hi,
Got a question about Reference pointers, and how to flatten them when assembling objects. Let's say I have a Practitioner resource like the following, and I want to resolve the managingOrganization reference.

{
  "resourceType" : "Practitioner",
  "name" : {
    "given" : "Beverly",
    "family" : "Crusher"
  },
  "practitionerRole" : [{
    "managingOrganization": {
      "display" : "Starfleet",
      "reference": "https://myapp.com/fhir/Organizations/001"
    }
  }]
}

Is the proper way to resolve the reference and flatten the object to attach the Organization at the reference field?

{
  "resourceType" : "Practitioner",
  "name" : {
    "given" : "Beverly",
    "family" : "Crusher"
  },
  "practitionerRole" : [{
    "managingOrganization": {
      "display" : "Starfleet",
      "reference" : {
        "resourceType" : "Organization",
        "active" : true,
        "name" : "Starfleet",
        "partOf" : {
          "display" : "Federation of Planets"
        }
      }
    }
  }]
}

Or should we replace the entire Reference resource?

{
  "resourceType" : "Practitioner",
  "name" : {
    "given" : "Beverly",
    "family" : "Crusher"
  },
  "practitionerRole" : [{
    "managingOrganization": {
      "resourceType" : "Organization",
      "active" : true,
      "name" : "Starfleet",
      "partOf" : {
        "display" : "Federation of Planets"
      }
    }
  }]
}

My assumption is that it's the former (which is how I've been implementing for the past few months). But the latter is more concise and coherent, and I'm not ruling out the possibility I've been doing things wrong for awhile now. Just want to confirm that I'm interpreting the standard correctly. Are there any discussions or best practices on the best way to handle this kind of object assembly? I suspect this dovetails into the discussions about JSON-LD and other linked data best practices.

view this post on Zulip Vadim Peretokin (Dec 11 2016 at 21:06):

Wouldn't you just use a contained resource here, or is this some next-gen stuff I'm not on top of?

view this post on Zulip Grahame Grieve (Dec 11 2016 at 21:11):

looks like a private implementation consideration to me. e.g. the Java reference implementation has an adornment on referece so that you can connect the resource being referred to the reference once you've resolved it, to save you resolving it again

view this post on Zulip Vadim Peretokin (Dec 11 2016 at 21:14):

Fair enough... can't see the cons for using contained if you're inloning it though, wouldn't that solve some troubles for you

view this post on Zulip Grahame Grieve (Dec 11 2016 at 21:15):

using contained screws over anyone you send to. So you should never do it for external consumption

view this post on Zulip Abbie Watson (Dec 11 2016 at 21:39):

Mostly this is just about internal implementation. I should note that we use Mongo and Redis, which are both schemaless datastores, so it's trivial for us to persist a flattened object to memory. No need to deconstruct or normalize. Which means that, given our own devices, we would implement interop between our apps where it's permissible to send an entirely flattened and resolved object from one app to the next.

It's sounding like the standard expects the resources to never be resolved or flattened? ie. Endpoints should never be implemented with JOIN or $lookup operators?

view this post on Zulip Grahame Grieve (Dec 11 2016 at 21:43):

so I have no idea what that last sentence means. But the standard is solely concerned with your interface; it says - and will say - nothing about what happens internally.

view this post on Zulip Grahame Grieve (Dec 11 2016 at 21:43):

the nearest we've come to that is some interest in fixing a HADOOP format, so that people can use a HADOOP database as their interface. But this hasn't gone anywhere

view this post on Zulip Abbie Watson (Dec 11 2016 at 21:46):

:)
JOIN and $lookup operators are database functions. From what I'm gathering, it's basically expected that the Practitioner endpoint only returns data from the Practitioner table; and wouldn't go off to an Organization table and $lookup the relevant organization, or JOIN that organization record to the queried practitioner record.

view this post on Zulip Grahame Grieve (Dec 11 2016 at 21:47):

are you talking about _include?

view this post on Zulip Abbie Watson (Dec 11 2016 at 21:47):

Ah. Maybe?

view this post on Zulip Grahame Grieve (Dec 11 2016 at 21:49):

so you can get asked to include the related records - you appen them to the bundle

view this post on Zulip Abbie Watson (Dec 11 2016 at 21:50):

Aaaaah. 2.1.1.5.3 Yeah, this is getting close to what I'm interested in figuring out.

view this post on Zulip Abbie Watson (Dec 11 2016 at 22:11):

Okay, so over the wire, we use a Bundle resource. And we get something like this.

{
  "resourceType" : "Bundle",
  "type" : "searchset",
  "entry" : [{
    "display" : "Beverly Crusher",
    "reference" : "https://myapp.com/fhir/Practitioner/12345"
  }, {
    "display" : "Starfleet",
    "reference" : "https://myapp.com/fhir/Organizations/001"
  }]
}

But then we're back to the original question. Is it permissible to resolve the above reference, and send the following over the wire?

{
  "resourceType" : "Bundle",
  "type" : "searchset",
  "entry" : [{
    "resourceType" : "Practitioner",
    "name" : {
      "given" : "Beverly",
      "family" : "Crusher"
    },
    "identifier" : [{
      "use" : "system",
      "value" : "12345"
    }], 
    "practitionerRole" : [{
      "managingOrganization": {
        "display" : "Starfleet",
        "reference": "https://myapp.com/fhir/Organizations/001"
      }
    }]
  }, {
    "resourceType" : "Organization",
    "identifier" : [{
      "use" : "system",
      "value" : "001"
    }],
    "active" : true,
    "name" : "Starfleet",
    "partOf" : {
      "display" : "Federation of Planets"
    }
  }]
}

Obviously, I need to dig deeper into the test specs, and do more interop testing with external systems. Which is what I'm trying to do. Trying to figure out exactly where to begin with these more complex resources.

view this post on Zulip Christiaan Knaap (Dec 13 2016 at 14:45):

You can try an example on Spark. It gives you 1 Patient with it's managing organization included.


Last updated: Apr 12 2022 at 19:14 UTC