Stream: shorthand
Topic: Issue creating Bundle instance
Alejandro Metke (Feb 17 2020 at 03:45):
I am trying to create an instance of a Bundle in FSH but I am getting errors in Sushi. Here is a fragment of my FSH file:
Instance: RareDiseaseBundle InstanceOf: Bundle Title: "Rare Disease Bundle" * type = #document * identifier.system = "http://ga4gh.org/fhir/phenopackets/" * identifier.value = "1" * entry[0].resource = RareDiseasePhenopacket * entry[1].resource = Proband
RareDiseasesPhenopacket is a Composition instance and Proband is a Patient instance. Here is the error message that I get:
error: mismatched input 'RareDiseasePhenopacket' expecting {'true', 'false', STRING, MULTILINE_STRING, NUMBER, CODE, DATETIME, TIME, REFERENCE} File: /Users/met045/CSIRO/workspaces/projects/fhir-phenopackets/phenopackets-examples.fsh Line: 128
Note that the entries are not references to the resources but the actual resources that are meant to be contained in the bundle. Is this supported by Sushi or am I missing something?
Nick Freiter (Feb 17 2020 at 12:57):
SUSHI doesn't support that type of syntax. To SUSHI, entry
is an array of type Resource
, so each entry can only have the fields defined on Resource
itself (id
, meta
, implicitRules
, language
). So a valid Bundle
could look something like this:
Instance: MyBundle InstanceOf: Bundle * entry[0].resource.id = "resource-1" * entry[1].resource.id = "resource-2"
This issue has also recently come up in the context of contained resources, https://chat.fhir.org/#narrow/stream/215610-shorthand/topic/contained.20resources, and one of the approaches we are considering is the one you attempted to use here, allowing Instances
to be inserted inline into another Instance
that has a field of type Resource
. It's helpful to see that that seemed like a natural approach for you. But we are tracking this and plan to address it.
Chris Moesel (Feb 17 2020 at 13:34):
It's interesting that no one has tried to do this yet until now, and in the last few days we've received reports from three separate people. It sounds like we should try to fast-track a solution on this one.
Jose Costa Teixeira (Feb 17 2020 at 13:36):
this = you mean contained resources?
Chris Moesel (Feb 17 2020 at 13:39):
this = creating instances w/ inlined (not referenced) resources -- which applies to both contained
as well a bundle
entries. I thinking whatever approach we use for one will likely apply to the other as well.
Jose Costa Teixeira (Feb 17 2020 at 14:22):
that is the same thing, right?
Jose Costa Teixeira (Feb 17 2020 at 14:22):
Both DomainResource and Bundle have elements whose type is Resource
David Hay (Feb 17 2020 at 17:46):
entry is an array of type Resource,
Just being pedantic - entry is a Backbone element so the array type is not Resource - right? And you can set the other entry elements (I checked) :) ...
Chris Moesel (Feb 17 2020 at 18:04):
Right -- the resource
is actually a field in each bundle entry.
Alejandro Metke (Feb 17 2020 at 22:31):
Great! Glad that you are thinking about a way to address this. It's not critical for me at the moment but definitively a nice to have.
Chris Moesel (Feb 19 2020 at 20:52):
So I've thought of this a bit more and wanted to get some input. I'm thinking we probably want to support a by-reference approach (like @Alejandro Metke tried to do) and an inline approach.
Chris Moesel (Feb 19 2020 at 20:54):
For the By-Reference approach, we'd also want a way to flag that the inlined instances should not result in indepedendent instances being exported (we only want the top-level instance), so maybe something like:
Instance: ShortyBundle InstanceOf: Bundle * type = #collection * entry[0].resource = Shorty * entry[1].resource = Ick Instance: Shorty InlineInstanceOf: Patient * name[0].given[0] = "Shorty" * name[0].family = "Fish" Instance: Ick InlineInstanceOf: Condition * code = SCT#12345 "Ick"
Chris Moesel (Feb 19 2020 at 20:55):
For the inline approach, we need a way to indicate to SUSHI what the inlined type is. So maybe something like this:
Instance: ShortyBundle InstanceOf: Bundle * type = #collection * entry[0].resource instanceOf Patient * entry[0].resource.id = "Shorty" * entry[0].resource.name[0].given[0] = "Shorty" * entry[0].resource.name[0].family = "Fish" * entry[1].resource instanceOf Condition * entry[1].resource.id = "Ick" * entry[1].resource.code = SCT#12345 "Ick"
Chris Moesel (Feb 19 2020 at 20:58):
Both of these would also apply to things like contained
-- but also in cases where you want an instance to use a profile as a path value (e.g., in an instance of Observation, make valueQuantity
an instance of a specific profile on Quantity).
Chris Moesel (Feb 19 2020 at 20:59):
Anyway, feedback is welcome and appreciated.
Mark Kramer (Feb 19 2020 at 21:06):
I think you have this backwards:
Instance: Ick InlineInstanceOf: Condition
It seems more clear as:
InlineInstance: Ick InstanceOf: Condition
Would ContainedInstance
be better?
David Hay (Feb 20 2020 at 03:11):
Which is the parent resource? It can't be Bundle...
Chris Moesel (Feb 20 2020 at 03:18):
I think you have this backwards:
Actually, the reason I suggested it that way was for consistency w/ how we're treating example. I believe that the consensus was that:
Conformance instances should be:
Instance: MyCapabilityStatement InstanceOf: CapabilityStatement
and examples should be:
Instance: MyCondition ExampleOf: Condition
So... it seems like the consistent approach is that ALL instances are Instance
s, but that the second keyword (InstanceOf
, ExampleOf
, InlineInstanceOf
) indicates the context.
Chris Moesel (Feb 20 2020 at 03:23):
That said, we haven't implemented that for examples yet, so I am 100% fine with walking that back and changing it such that we have:
ConformanceInstance: MyCapabilityStatement InstanceOf: CapabilityStatement //... Example: MyCondition InstanceOf: Condition //... ContainedInstance: MyContainedCondition InstanceOf: Condition //...
In fact, I think I personally prefer something like that (but can't decide exactly on the names Instance
vs ConformanceInstance
vs Conformance
-- or ContainedInstance
vs Contained
)...
Chris Moesel (Feb 20 2020 at 03:25):
Another approach:
Instance: MyCapabilityStatement InstanceOf: CapabilityStatement Type: Conformance //... Instance: MyCondition InstanceOf: Condition Type: Example //... Instance: MyContainedCondition InstanceOf: Condition Type: Contained // or Inline //...
Oh. I think I like that one best, even if it is more lines of FSH. I feel like it is easier to remember.
Nick Freiter (Feb 20 2020 at 12:20):
I'd vote for that last syntax,. Maybe we make Type: Example
the default? Since that has pretty much been the default so far.
Jose Costa Teixeira (Feb 20 2020 at 12:24):
How can we make a contained resource inside a resource inside a bundle?
Jose Costa Teixeira (Feb 20 2020 at 12:24):
I think whatever syntax it is, must support that
Jose Costa Teixeira (Feb 20 2020 at 12:25):
must/should (but I think Must)
Chris Moesel (Feb 20 2020 at 13:41):
How can we make a contained resource inside a resource inside a bundle?
I think either syntax (the by-reference or inline syntax) would support this. You're just reapplying the same approach at a different level of the path. Do you want an example, or does that make sense as I described it?
Jose Costa Teixeira (Feb 20 2020 at 14:25):
I struggle with the "Type". And where do we indicate what is it contained in?
Jose Costa Teixeira (Feb 20 2020 at 14:25):
Say we have a bundle of 2 prescriptions, each with contained medication
Jose Costa Teixeira (Feb 20 2020 at 14:25):
what will the fsh look like?
Jose Costa Teixeira (Feb 20 2020 at 14:26):
how do we say that prescription 1 has medication 1 and prescription 2 has medication 2?
Jose Costa Teixeira (Feb 20 2020 at 14:26):
I was thinking that this is done by nesting or pointing to the parent.
Jose Costa Teixeira (Feb 20 2020 at 14:27):
(in which case "Type=contained" is redundant, right?)
Jose Costa Teixeira (Feb 20 2020 at 14:27):
and actually while typing this i realized:
Jose Costa Teixeira (Feb 20 2020 at 14:29):
Yes, please give an example FSH (can be the example I mention).
Normally I would not ask that because it could be a lot of work to make and read those resources, but that is no longer a big issue with FSH.
Jose Costa Teixeira (Feb 20 2020 at 14:30):
Which is really cool, and I'm grateful .You made it easier to share examples in FSH form, so yes, let's see it.
Chris Moesel (Feb 20 2020 at 14:41):
So if you use the proposed syntax that allows you to define a "contained" resource separately (with Type: Contained
) -- that "contained" resource is re-usable. It doesn't point to the instance that contains it. Rather, the instance that contains it explicitly references it by name. I can provide an example later, but right now have to head into some meetings. That said, your question has given me another idea as well -- so I'll see if I can work that idea into the example too.
Chris Moesel (Feb 20 2020 at 14:57):
Also -- I think that since these instances can be used in contained
(literally contained) as well as in other places that allow inline resource instances -- maybe it makes sense for the Type
to be Inline
, otherwise there might be confusion.
Chris Moesel (Feb 20 2020 at 15:32):
@Jose Costa Teixeira -- here is an example of your scenario using one of the proposed syntaxes:
Instance: PrescriptionBundle InstanceOf: Bundle Type: Example * entry[0].resource = Prescription1 * entry[1].resource = Prescription2 // ... more rules Instance: Prescription1 InstanceOf: MedicationRequest Type: Inline * contained[0] = Medication1 * medicationReference = "#Medication1" // ... more rules Instance: Prescription2 InstanceOf: MedicationRequest Type: Inline * contained[0] = Medication2 * medicationReference = "#Medication2" // ... more rules Instance: Medication1 InstanceOf: Medication Type: Inline * code = RXNORM#12345 // ... more rules Instance: Medication2 InstanceOf: Medication Type: Inline * code = RXNORM#67890 // ... more rules
Chris Moesel (Feb 20 2020 at 15:34):
Since all but the bundle have Type: Inline
-- the only resource that is actually exported is the bundle -- but it has Prescription1
and Prescription2
inlined in the entry.resource
array, Medication1
inlined in Prescription1
's contained
array, and Medication2
inlined in Prescription2
's contained
array.
Chris Moesel (Feb 20 2020 at 15:35):
(deleted)
Chris Moesel (Feb 20 2020 at 15:37):
But this led me to the idea that this is needlessly verbose:
Instance: Prescription1 InstanceOf: MedicationRequest Type: Inline * contained[0] = Medication1 * medicationReference = "#Medication1" // ... more rules
We could support using the reference directly like this as well:
Instance: Prescription1 InstanceOf: MedicationRequest Type: Inline * medicationReference = Medication1 // ... more rules
SUSHI would be smart enough to see that Medication1
has type Inline
, so it would know to automatically add it to the contained
array and make the reference a local reference to Medication1
.
Chris Moesel (Feb 20 2020 at 15:46):
And... since no one asked... here is what that same scenario looks like using the syntax that defines all the inline resources inline in the FSH:
Instance: PrescriptionBundle InstanceOf: Bundle Type: Example * entry[0].resource instanceOf MedicationRequest * entry[0].resource.id = "Prescription1" * entry[0].resource.contained[0] instanceOf Medication * entry[0].resource.contained[0].id = "Medication1" * entry[0].resource.contained[0].code = RXNORM#12345 // ... more entry[0].resource.contained[0] rules * entry[0].resource.medicationReference = "#Medication1" // ... more entry[0].resource rules * entry[1].resource instanceOf MedicationRequest * entry[1].resource.id = "Prescription2" * entry[1].resource.contained[0] instanceOf Medication * entry[1].resource.contained[0].id = "Medication2" * entry[1].resource.contained[0].code = RXNORM#67890 // ... more entry[1].resource.contained[0] rules * entry[1].resource.medicationReference = "#Medication2" // ... more entry[1].resource rules
Mark Kramer (Feb 20 2020 at 15:54):
Very interesting discussion. Here's my take:
1) The "Type" keyword is much cleaner than trying to generalize "InstanceOf" to "ExampleOf", "InlineInstanceOf" etc. Thumbs up for "Type"
2) The inline syntax is just hard to read. I'm not in favor of introducing an "instanceOf" rule. Thumbs down on "* foo instanceOf bar"
3) I agree SUSHI should be smart enough to figure out the population of "contained" itself. Thumbs up on the direct assignment of an inline Type to a reference.
Chris Moesel (Feb 20 2020 at 16:19):
I'm personally in favor of the inline syntax if for no other reason than it is consistent with our approach elsewhere (we allow other things inline) and it allows for an instance in FSH to be fully self-contained. I also feel like it would be useful elsewhere.
Consider that there are other places where an author may want a specific property to be an instance of a profile, not an instance of the vanilla type declared by the property. Here is a contrived example... Imagine a user wants to create an instance of Invoice
. And in the invoice they are creating multiple lineItem
s. They want their instance to create instances of USMoney
(a profile on Money
) -- but Invoice
only declares the field as normal Money
. Here is how they do it w/ the inline syntax:
* lineItem[0].priceComponent[0].amount instanceOf USMoney * lineItem[0].priceComponent[0].amount.value = 2.00 * lineItem[1].priceComponent[0].amount instanceOf USMoney * lineItem[1].priceComponent[0].amount.value = 2.50 * lineItem[2].priceComponent[0].amount instanceOf USMoney * lineItem[2].priceComponent[0].amount.value = 3.00
Without the inline syntax, they would need to create a separate Instance:
entity for every single USDollar amount they want in that instance. If they have 20 line items, that gets pretty cluttered.
Chris Moesel (Feb 20 2020 at 16:20):
That said, I had to talk @Nick Freiter into the inline syntax too, and he's a pretty smart guy as well. So... I realize that I may be in the minority on this one. That being the case, unless others are clamoring for it, I'd propose we support the other (by-reference) syntax first and only support the inline-defined syntax if people start asking for it.
Grahame Grieve (Feb 20 2020 at 20:27):
on the subject of verbose...
Grahame Grieve (Feb 20 2020 at 20:27):
Instance: Prescription1 InstanceOf: MedicationRequest
Grahame Grieve (Feb 20 2020 at 20:27):
for any one used to text based languages, this is clunky. Why not
Instance Prescription of MedicationRequest?
Jose Costa Teixeira (Feb 20 2020 at 20:41):
@Chris Moesel your example seems to introduce one limitation - the contained resources cannot both be called Medication1 (which i presume is possible in FHIR)
Jose Costa Teixeira (Feb 20 2020 at 20:41):
this is not really important but makes me think: How will all of this work with resource versions?
Jose Costa Teixeira (Feb 20 2020 at 20:42):
in my IG i have a care plan with 3 versions - but this is not supported so I have to have 3 different care plan IDs
Jose Costa Teixeira (Feb 20 2020 at 20:44):
How much of this syntax breaks when we need to have multiple resource instances with id=careplan001 and versions 1, 2, 3.. ?
Jose Costa Teixeira (Feb 20 2020 at 20:46):
- I think I like more the message when you went "since no one asked" @Chris Moesel
Jose Costa Teixeira (Feb 20 2020 at 20:47):
- would it be interesting to do
* entry[0].resource.contained[0] instanceOf Medication alias Medication1
and then use that alias everywhere?
Jose Costa Teixeira (Feb 20 2020 at 20:50):
Instance Prescription of MedicationRequest
I like this. I'd read it better if it were Prescription=instance(MedicationRequest) or Prescription=example(MedicationRequest) but I don't think that is how the shorthand grammar is being defined
Mark Kramer (Feb 20 2020 at 23:24):
The verbosity, if it is that, comes from the structure of Shorthand items. Each item starts with a set of keyword declarations, followed by a set of rules. The declarations are the part that goes:
Instance: Foo InstanceOf: Bar Description: "Blah blah blah"
These declarations set the stage for the defining the rules (statements that begin with a bullet *) that actually do the profiling, fixing, or binding. It might not be the absolute most compact way to do things, but this basic arrangement is very clear to users.
Jean Duteau (Mar 26 2020 at 14:48):
I have this issue right now and I see talk of a solution, but I can't tell from browsing the issue log if this ever got added or if we are still discussing. If this hasn't been added, is there a workaround on how to set the bundle.entry.resource to be different instances?
Chris Moesel (Mar 26 2020 at 16:16):
Hi @Jean Duteau -- support for inline instances (which is what you need here) will be in our next release of SUSHI. We're aiming for tomorrow afternoon, although it might be early next week if we hit any snags. The basic approach is you define instances you want in the bundle the normal way but with this additional metadata: Usage: #inline
. Then in your bundle, you can say: bundle.entry[0].resource = MyResource
.
Jean Duteau (Mar 26 2020 at 16:18):
okay, i thought I might have to wait. will this work if I want to have the instance exist as a separate example as well? i.e. I have a Composition instance that I want to exist as a Composition example in my IG. I also want to just have the Bundle include that already-defined Composition instance as one of its entries.
Chris Moesel (Mar 26 2020 at 16:22):
Yes, in that case, you'd set the Usage:
to #example
and it would export as a separate example and be inlined in your bundle.
Jean Duteau (Mar 26 2020 at 16:23):
muchas gracias!
Etienne Cantineau (Apr 09 2020 at 07:18):
Hello, i have understood how to create bundle with bundle.entry[0].resource = MyResource and inline instances but now i'm working on a bundle with sliced mandatory entries, one is patient and i'm trying this: bundle.entry[patient].resource = patient1 with an inline instance of Patient profile. I receive the error: Cannot fix Resource value: patient1. Value does not match element type: Patient. Any idea what's wrong?
Nick Freiter (Apr 09 2020 at 12:29):
What you are trying to do makes sense, but isn't possible yet due to a limitation of SUSHI. We currently only support setting fixed inline instances on elements of type Resource, not specific sub-types of Resource, such as Patient in your case. We do plan to extend this so that we support setting inline instances to sub-types of Resource, but haven't been able to address it yet. I've created an issue here https://github.com/FHIR/sushi/issues/347 to track this task.
Etienne Cantineau (Apr 09 2020 at 13:03):
@Nick Freiter Thank you for your answer. I'll follow that
Chris Moesel (Apr 15 2020 at 19:14):
Hi @Etienne Cantineau - this is fixed in the newly released SUSHI 0.12.1.
Etienne Cantineau (Apr 16 2020 at 07:37):
Thank you, it can now reach correctly my inline instances! That lead me to another problem!
I have my patient inline instance with Usage: #inline, i've read that it doesn't create xml/json files and then, i receive the message from the IG "Publishing content failed: unable to find the source file for Patient/Patient1: not specified, so tried Patient-Patient1.xml, json etc".
Why is the publisher still looking for a file? Or am i missing something?
I didn't encounter that problem when i tested bundle creation because in my previous test without Usage keyword, sushi had created a json file of my patient instance.
Nick Freiter (Apr 16 2020 at 12:03):
It looks like the Patient1 resource is incorrectly being added by SUSHI to the ImplementationGuide.json file, even though it is specified as inline, I've logged this as an issue here https://github.com/FHIR/sushi/issues/366. Sorry to fix one issue only to have you run into another, but thanks for reporting so we can fix this!
Etienne Cantineau (Apr 16 2020 at 12:12):
Ok, no problem, i'm not in a hurry!
Etienne Cantineau (Apr 20 2020 at 09:25):
The problem is well solved! I see that the inline instances are counted in the sushi results report, maybe they shouldn't as they are not standalone files unlike the other resources of the report.
Etienne Cantineau (Apr 20 2020 at 11:26):
One more thing about these bundles: i got an error from the publisher "org.hl7.fhir.exceptions.FHIRException: No fullUrl on entry #1 in Bundle slicedbundle1". This element fullUrl is however 0..1. After investigations, i found i only get errors from the instances that have references.
If i put in comment the lines where i use a reference, i don't get my error anymore.
You can see the profile and example here: https://github.com/ec-ehealth/Bundle-example
Chris Moesel (Apr 20 2020 at 13:20):
Hi @Etienne Cantineau -- it looks like the FHIR spec requires fullUrl
in order to resolve relative references. See: http://hl7.org/fhir/R4/bundle.html#references
So, it looks like you'll need to add fullUrl
values to your bundle as well...
Etienne Cantineau (Apr 20 2020 at 14:33):
Ok thank you, i didn't know it was mandatory in that case. No problem, i'll add that!
Last updated: Apr 12 2022 at 19:14 UTC