Stream: implementers
Topic: Representing Extensions
Mark Kramer (Mar 04 2016 at 14:29):
Can I perhaps direct your collective attention to a blog post by Marc Hadley, suggesting an alternate method of representing extensions? It is on lightmyfhir.org (http://lightmyfhir.org/2016/02/26/an-alternate-xml-syntax-for-fhir-extensions). I don't know if Marc's suggestion has gotten any eyeballs yet. The post deals with XML, but we are also preparing a post with a JSON version. Marc did this in response to Grahame's call for feedback (see http://www.healthintersections.com.au/?p=2467) so I hope some of you will have a look.
Josh Mandel (Mar 04 2016 at 21:09):
Thanks for the link @Mark Kramer ! There was definitely some discussion of namespaces (see "Brian's Thoughts"). I'm interested to see @Marc Hadley's JSON-focused follow-up.
Grahame Grieve (Mar 05 2016 at 01:06):
I do so abominate namespaces, but I will reserve further comment until I've seen the JSON representation
Grahame Grieve (Mar 05 2016 at 01:07):
this would also be possible:
Grahame Grieve (Mar 05 2016 at 01:08):
<Patient xmlns="http://hl7.org/fhir" xmlns:fhir="http://hl7.org/fhir"> <id value="patient-example"/> ... <ct:clinicalTrial xmlns:ct="http://hl7.org/fhir/StructureDefinition/patient-clinicalTrial" fhir:isModifier="false"> <ct:NCT xsi:type="string" value="NCT01647425"/> <ct:Period xsi:type="Period"> <start value="2012-04-01"/> <end value="2013-09-30"/> </ct:Period> <ct:Reason xsi:type="CodeableConcept"> <coding> <system value="http://snomed.info/sct"/> <code value="254637007"/> <display value="NSCLC - Non-small cell lung cancer"/> </coding> </ct:Reason> </ct:clinicalTrial> ... </Patient>
Grahame Grieve (Mar 05 2016 at 01:09):
And: "Code generation still works, tools like JAXB have no problem with XML schemas that include extensions defined elsewhere"
Grahame Grieve (Mar 05 2016 at 01:10):
is that true about lax? jaxb ignores anything in other namespaces, or it just blows up?
Grahame Grieve (Mar 05 2016 at 01:10):
what about other code generators?
Grahame Grieve (Mar 05 2016 at 01:12):
however, this explicitly breaks my most important requirement as I noted on a task on the original post, which has been ignored: all implementers can read and write all extensions when they generate code
Grahame Grieve (Mar 05 2016 at 01:13):
as for: "I don't know if Marc's suggestion has gotten any eyeballs yet" - I hadn't seen it until you posted it here. Should I have seen it from elsewhere?
Mark Kramer (Mar 05 2016 at 22:34):
Grahame, thank you for the feedback. I don't understand what you mean by "breaks my most important requirement...all implementers can read and write all extensions when they generate code." Can you explain the situation where you envision there being a problem? Why wouldn't they be able to read and write extensions under Marc's proposed representation?
Mark Kramer (Mar 05 2016 at 23:02):
I didn't mean to imply anything, just asking for feedback.
Grahame Grieve (Mar 06 2016 at 08:06):
hi Mark. In the approach you are proposing, If I generate code from the base schema, I'll lose all the extensions, yes?
Eric Prud'hommeaux (Mar 07 2016 at 10:33):
Grahame , when you say "generate code from the base schema", do you mean you want to use code that navigates exclusively the vocabulary defined in the schema to serialize extensions?
Marc Hadley (Mar 07 2016 at 14:44):
You wouldn't lose all of the extensions, at least you wouldn't if you were using JAXB. An xsd:any is mapped to a property of type Object[]. That array will be populated with either Element objects or instances of JAXB objects defined in extension schemas that were included in the JAXB context. See the examples here and the documentation of the lax annotation property: https://jaxb.java.net/nonav/2.1.3/docs/api/javax/xml/bind/annotation/XmlAnyElement.html.
Marc Hadley (Mar 07 2016 at 14:52):
I posted the accompanying proposal for an alternate JSON syntax here: http://lightmyfhir.org/2016/03/07/an-alternate-json-syntax-for-fhir-extensions/
Josh Mandel (Mar 07 2016 at 15:26):
Hmm. This is sort of JSON-LD inspired, sure. You say that you have not adopted to JSON LD wholesale, but actually I think what you have proposed here is not even quite compatible with that specification. Because you are relying on certain implicit behavior to handle nested complex extensions. So you could not use a JSON LD library out of the box. Is that right?
Marc Hadley (Mar 07 2016 at 15:41):
That's right. Really the only part of JSON-LD used in this proposal is the namespacing of extension names.
Marc Hadley (Mar 07 2016 at 15:42):
That might confuse folks so it might be better to not use @context but rename it to @namespace or some such
Grahame Grieve (Mar 07 2016 at 19:05):
note that RDF <> json-ld. We can't use json-ld
Grahame Grieve (Mar 07 2016 at 19:07):
what's the scope of @context? There's a reason we studiously avoid manifests in HL7 content - you won't find it anywhere else
Grahame Grieve (Mar 07 2016 at 19:08):
this question is a very big deal for me in with regard to this proposal
Grahame Grieve (Mar 07 2016 at 19:08):
and relates directly to why we can't use json-ld
Grahame Grieve (Mar 07 2016 at 19:09):
note that we could also move the type into the manifest too
Grahame Grieve (Mar 07 2016 at 21:30):
anyway, I think you should be narrow, and call this @extension and way that the extension definition applies to siblings of the element on which it is declared, and on all children, but *not* on parents or siblings of parents (e.g. same scope as xml namespaces)
Grahame Grieve (Mar 07 2016 at 21:30):
.. and say.. not .. and way... (don't know why I can't edit that one)
Marc Hadley (Mar 07 2016 at 21:43):
Grahame, agreed. I'd go a bit further and say that definitions do not apply to grandchildren or their descendants. If, e.g. I define a "code" extension that shouldn't apply to any deeper scoped use of that name as those are already defined by the semantics of the parent.
Grahame Grieve (Mar 07 2016 at 21:44):
have to repeat the extension definition ad nauseam?
Marc Hadley (Mar 07 2016 at 21:45):
IOW, the @extension just applies to the extensions at this level. If you extend extensions then you need to add in a new @extension to identify the extensions extension.
Grahame Grieve (Mar 07 2016 at 21:46):
I'm thinking of the case .. in code system and questionaire .. where concepts contain concepts and questions contain questions
Marc Hadley (Mar 07 2016 at 21:46):
I feel another example coming on...
Grahame Grieve (Mar 07 2016 at 21:46):
if you use an extension on a concept, you're likely to use them on contained concepts too
Marc Hadley (Mar 07 2016 at 21:47):
Good point. I think there are pros and cons here.
Marc Hadley (Mar 07 2016 at 22:02):
Maybe we could say that the @extension defines names of extensions but doesn't override existing properties with the same name.
Grahame Grieve (Mar 07 2016 at 22:08):
yes it sure can't do that. Wonder if there's naming restrictions we would need to ensure that you don't create name clashes
Grahame Grieve (Mar 08 2016 at 01:52):
Marc, thinking more about this- I think this has real problems
Grahame Grieve (Mar 08 2016 at 01:52):
patient = {...second example above...} nct = patient["patient-clinicalTrial"].NCT.valueString
Grahame Grieve (Mar 08 2016 at 01:53):
only, you can't. you actually have a much worse problem than that the original code
Grahame Grieve (Mar 08 2016 at 01:55):
patient = {...first example above...} clinicalTrials = element for name as found in @context @id is "http://hl7.org/fhir/StructureDefinition/patient-clinicalTrial" nct = nct.clinicalTrails.valueString
Grahame Grieve (Mar 08 2016 at 01:55):
e.g. we would be subsituting looking up the extension for looking up the name gained by looking up the extension. I think this is worse, not better
Grahame Grieve (Mar 08 2016 at 10:57):
I just re-read all the blog posts. I think I now understand what you think you mean by 'treat extensions and normal elements the same' and, I'm afraid, you won't be able to treat them the same - and, in fact, you haven't even started to do so. They're different. Sorry
Marc Hadley (Mar 08 2016 at 12:57):
I see what you are getting at, but I still think its better. Compare:
Marc Hadley (Mar 08 2016 at 12:58):
clinicalTrials = (extension for extension in patient.extension when extension.url is "http://hl7.org/fhir/StructureDefinition/patient-clinicalTrial") ncts = (extension for extension in clinicalTrials[0].extension when extension.url is "NCT") nct = ncts[0].valueString
Marc Hadley (Mar 08 2016 at 12:58):
vs
Marc Hadley (Mar 08 2016 at 12:59):
localname = (localname for localname, defn of patient2["@context"] when defn["@id"] is "http://hl7.org/fhir/StructureDefinition/patient-clinicalTrial")[0] nct = patient2[localname].NCT.valueString
Grahame Grieve (Mar 08 2016 at 13:00):
so you made complex extensions slightly easier at the price of making simple extensions harder
Marc Hadley (Mar 08 2016 at 13:00):
(the second being the proposed, the first being current)
Grahame Grieve (Mar 08 2016 at 13:01):
and it's unsafe, since almost all javascript programmers will refuse to use that method, and just use the 'fixed' name, only it's not fixed, and can't be
Marc Hadley (Mar 08 2016 at 13:01):
Are simple extensions actually harder though? With the current representation you still have to loop over an array looking for the one you want.
Grahame Grieve (Mar 08 2016 at 13:02):
here, you have a double loop
Grahame Grieve (Mar 08 2016 at 13:02):
to get the name you want.
Grahame Grieve (Mar 08 2016 at 13:02):
then use it
Grahame Grieve (Mar 08 2016 at 13:02):
as opposed to just looking for the extension you want
Marc Hadley (Mar 08 2016 at 13:03):
There's only one loop
Grahame Grieve (Mar 08 2016 at 13:03):
this is much harder than simply using the full extension name as the property, which was roundly rejected when we tried that
Marc Hadley (Mar 08 2016 at 13:04):
The other approach would be to move further away from JSON-LD and invert the extension map to put URI as the key then its just map lookups all the way
Grahame Grieve (Mar 08 2016 at 13:05):
I think that's what we tried. As simple as we could. and it got voted down strongly
Grahame Grieve (Mar 08 2016 at 13:05):
it wasn't perfect; we still had to deal with modifier extensions.
Grahame Grieve (Mar 08 2016 at 13:05):
so I'm skeptical. I think
Marc Hadley (Mar 08 2016 at 13:05):
I included modifiers in my proposal
Grahame Grieve (Mar 08 2016 at 13:05):
but lets see other opinions
Marc Hadley (Mar 08 2016 at 13:06):
Example:
patient = { "@extension" : { "http://hl7.org/fhir/StructureDefinition/patient-clinicalTrial": { "@localname": "clinicalTrial", "@isModifier": false } } "resourceType" : "Patient", "clinicalTrial" : { "NCT" : { "valueString" : "123456789" }, "period": { "valuePeriod" : { "start" : "2009-03-14" } }, "reason": { "valueCodeableConcept" : { "coding" : { "system" : "http://acme.org/codes/general", "code" : "tt14j" } } } } }
Grahame Grieve (Mar 08 2016 at 13:07):
so I still iterate the @extension, which needs to be an array, right? and then find the name then look for then name... why not just iterate the extensions?
Marc Hadley (Mar 08 2016 at 13:08):
localname = patient["@extension"]["@localname"] nct = patient[localname].NCT.valueString
Marc Hadley (Mar 08 2016 at 13:09):
@extension is an object since the keys are unique
Grahame Grieve (Mar 08 2016 at 13:10):
so you can only have one extension on an element at once?
Marc Hadley (Mar 08 2016 at 13:10):
one @extension with multiple children, one per extension
Grahame Grieve (Mar 08 2016 at 13:12):
remind me, what happens in javascript, if the extension is not defined, or not present, and you use the code above?
Marc Hadley (Mar 08 2016 at 13:13):
"@extension" : { "http://hl7.org/fhir/StructureDefinition/patient-clinicalTrial": { "@localname": "clinicalTrial", "@isModifier": false } "http://hl7.org/fhir/StructureDefinition/us-core-race": { "@localname": "race", "@isModifier": false } }
Marc Hadley (Mar 08 2016 at 13:16):
Just realized I messed up the code there, should have been:
localname = patient["@extension"]["http://hl7.org/fhir/StructureDefinition/patient-clinicalTrial"]["@localname"] nct = patient[localname].NCT.valueString
Marc Hadley (Mar 08 2016 at 13:17):
In this code if there's no @extension then you'd get back undefined which would throw a TypeError when you tried to get the local name property
Grahame Grieve (Mar 08 2016 at 13:18):
so the code is going to get more complex yet
Marc Hadley (Mar 08 2016 at 13:18):
Same goes for the current representation, I didn't put any error handling in that either
Grahame Grieve (Mar 08 2016 at 13:20):
well, the loop form is kind of more tolerant of missing items by it's nature. kind of
Grahame Grieve (Mar 08 2016 at 13:20):
I'm still not persauded. but it's sleep time, and so I'll see what others think
Marc Hadley (Mar 08 2016 at 13:27):
Personally I think the loop code is more complicated. A robust implementation has to handle missing and duplicate entries etc. My short code snippet just assumes there is one extension with the right URL and that it has one child extension for NCT (hence the [0] in a couple of places). These would blow the code up if the assumptions failed.
Marc Hadley (Mar 08 2016 at 13:31):
BTW, a more robust code snippet in CoffeeScript:
localname = patient["@extension"]?["http://hl7.org/fhir/StructureDefinition/patient-clinicalTrial"]?["@localname"] nct = patient[localname]?.NCT?.valueString
this yields undefined
for nct
if anything is missing
Lloyd McKenzie (Mar 08 2016 at 15:48):
Three concerns with the XML approach:
- xs:ANY is going to encourage people to send any XML they can dream up - including attributes and attributes with namespaces and other things that can't be round-tripped to JSON. We could introduce invariants, but it'd be complicated
- it's harder for people to handle extensions generically. There are times when you want to take all extensions and store them in a single way or to count them. (E.g. If you've got narrative that was generated from extensions, you want to quickly scan through all of the extension elements to see which ones you recognize)
- (minor) HL7-defined extensions would need a distinct namespace from the base spec, which makes resolving them to html more complicated
I share Grahame's concerns about the JSON. I see a lot of implementers taking the easy (wrong) route.
Marc Hadley (Mar 08 2016 at 18:30):
@Lloyd McKenzie could you give an example of what you mean by invariants in your first bullet above?
Lloyd McKenzie (Mar 08 2016 at 18:38):
Well, we could have an invariant as an xpath that indicated that only specific attributes are allowed. E.g. context = @*, assertion name=('id', ...)
However, that won't work as a FHIRPath because FHIRPath doesn't distinguish elements and attributes. So we might actually allow a new element on StructureDefinition to support doing this.
Grahame Grieve (Mar 08 2016 at 18:59):
HL7 defined extensions - that's a problem, because they're in the same namespace
Grahame Grieve (Mar 08 2016 at 18:59):
I missed that
Marc Hadley (Mar 08 2016 at 19:11):
Do they have to be in the same namespace? Possible to add some kind of ns suffix like /extension ?
Grahame Grieve (Mar 08 2016 at 19:12):
no, they're not. scratch that. They are in a differnt namespace (just same root)
Marc Hadley (Mar 08 2016 at 19:59):
@Lloyd McKenzie does the @context/@extension preamble meet your requirements for identifying extensions in the JSON format? Not sure of the best way to do that for XML, would prefer to avoid a wrapper element if possible.
Marc Hadley (Mar 08 2016 at 20:53):
Easy enough in XPath I guess: /*/*[namespace-uri(.)!="http://hl7.org/fhir"]
Lloyd McKenzie (Mar 08 2016 at 21:02):
I think you'd skip one of the /*, because you'd want direct children, but yes, that could work. @context doesn't work terribly well if it appears as a manifest at the top of the instance. It would need to be declared inside each node where extensions appear.
Marc Hadley (Mar 08 2016 at 21:05):
The first /* was to match any top level resource. Your use case is to find all extensions at any level or just those at the top level?
Lloyd McKenzie (Mar 08 2016 at 21:05):
The use-case is to find extensions for the current node
Marc Hadley (Mar 08 2016 at 21:06):
so ./*[namespace-uri(.)!="http://hl7.org/fhir"]
in XPath.
Marc Hadley (Mar 08 2016 at 21:09):
We didn't settle on scoping of @context/@extension, I was advocating for one per level of nesting but Grahame pointed out that would be a pain for extensions to types that nest.
Lloyd McKenzie (Mar 08 2016 at 21:20):
Manifests are a pain in general - they're either all over the place or they aren't in the context where you need them. Hard to find the right balance.
Marc Hadley (Mar 09 2016 at 16:27):
... or they are out of step with the actual content
Lloyd McKenzie (Mar 09 2016 at 16:33):
Yeah, that can be a challenge too.
Mark Kramer (Mar 09 2016 at 17:22):
You have to spell things out for me. I'm assuming you are referring to code generated at design time. At that time, there are no instances of resources, and no instances of extensions, so how can extensions they be lost? There are StructureDefinitions, but one can't assume a full set. Nonetheless, you can still parse and store whatever comes down the wire under our suggestion. You just don't know what the extensions mean, necessarily. I must be totally missing your point.
Lloyd McKenzie (Mar 09 2016 at 18:44):
The code written for processing an instance needs to be able to easily find the list of all extensions beneath a particular node. We have a solution that works for XML. The solution works for JSON only if the context is declared on every node (including recursive nodes.
Marc Hadley (Mar 09 2016 at 18:48):
One of the concerns with the proposed JSON representation is that the "local name" in JSON is essentially insignificant but naive developers might assume that it is fixed and ignore the mapping to a URI. I'm wondering if the team considered using qualified names to disambiguate local names, e.g.:
patient = { "resourceType" : "Patient", "org.hl7.clinicalTrial" : { "@extension": "http://hl7.org/fhir/StructureDefinition/patient-clinicalTrial", "@isModifier": false "NCT" : { "valueString" : "123456789" }, "period": { "valuePeriod" : { "start" : "2009-03-14" } }, "reason": { "valueCodeableConcept" : { "coding" : { "system" : "http://acme.org/codes/general", "code" : "tt14j" } } } } }
Marc Hadley (Mar 09 2016 at 18:49):
The above also breaks up the manifest and puts the extension id as a child of the top level extension (just like you use url in the current representation).
Lloyd McKenzie (Mar 09 2016 at 18:50):
How would you make those globally unique if they weren't a URI? And why have both?
Marc Hadley (Mar 09 2016 at 18:50):
I used a java-like org.hl7.clinicalTrial
but other naming schemes could work just as well.
Lloyd McKenzie (Mar 09 2016 at 18:51):
It seems weird to have two globally unique names
Marc Hadley (Mar 09 2016 at 18:51):
OIDs are globally unique without being URIs...
Lloyd McKenzie (Mar 09 2016 at 18:51):
Right. But we don't use OIDs
Marc Hadley (Mar 09 2016 at 18:51):
I think you mentioned earlier that developers didn't like using URIs as keys
Lloyd McKenzie (Mar 09 2016 at 18:52):
Right. They didn't like long strings as keys.
Rick Geimer (Mar 09 2016 at 18:52):
OIDs can be URIs. urn:oid:OID-HERE
Lloyd McKenzie (Mar 09 2016 at 18:52):
And this isn't going to be significantly shorter than the URL and would also be redundant with the URL.
Marc Hadley (Mar 09 2016 at 18:53):
org.hl7.clinicalTrial
is intended to work like an old, the authority org.hl7
is the only org that can use ids starting with that string and is responsible for ensuring uniqueness.
Lloyd McKenzie (Mar 09 2016 at 18:53):
@Rick Geimer True, but we discourage doing that. (And avoid doing it for anything HL7 Int'l is responsible for)
Rick Geimer (Mar 09 2016 at 18:53):
But in general I find my developers like the URIs with somewhat meaningful names.
Rick Geimer (Mar 09 2016 at 18:54):
And it's easier to teach someone to make up a URI for their company's patient IDs or internal codes than it is to ask them to get an OID from HL7.
Lloyd McKenzie (Mar 09 2016 at 18:54):
Especially now that they have to pay for the privilege of an OID once they've wrapped their heads around what it is . . .
Marc Hadley (Mar 09 2016 at 18:54):
I'd actually be OK with using URIs for keys like this:
patient = { "resourceType" : "Patient", "http://hl7.org/fhir/StructureDefinition/patient-clinicalTrial" : { "@isModifier": false "NCT" : { "valueString" : "123456789" }, "period": { "valuePeriod" : { "start" : "2009-03-14" } }, "reason": { "valueCodeableConcept" : { "coding" : { "system" : "http://acme.org/codes/general", "code" : "tt14j" } } } } }
but I didn't suggest it as I thought that was already rejected
Rick Geimer (Mar 09 2016 at 18:56):
Exactly Lloyd.
Marc Hadley (Mar 09 2016 at 19:00):
If we want a short globally unique name there aren't many alternatives to some kind of naming convention like that used in Java.
Grahame Grieve (Mar 09 2016 at 20:39):
Marc - indeed that was already rejected, and I think it's better than your proposal.
Grahame Grieve (Mar 09 2016 at 20:39):
which suggests to me that all this discussion is actually moot. :-(
Grahame Grieve (Mar 09 2016 at 20:42):
and it wasn't rejected because they were long, but because it deviated from the conceptual model which creates cognitive dissonance.
Marc Hadley (Mar 09 2016 at 21:01):
Grahame, I'm coming to the same conclusion but before I give up can you explain what you mean by "deviated from the conceptual model" - what conceptual model is that, where can I read about it?
Marc Hadley (Mar 10 2016 at 15:29):
Still noodling on this as I'm convinced we can get to a more readable/natural representation that the current one. How about the following:
{ "resourceType" : "Patient", "extension" : [ { "url": "http://hl7.org/fhir/StructureDefinition/patient-clinicalTrial", "isModifier": false "NCT" : { "valueString" : "123456789" }, "period": { "valuePeriod" : { "start" : "2009-03-14" } }, "reason": { "valueCodeableConcept" : { "coding" : { "system" : "http://acme.org/codes/general", "code" : "tt14j" } } } } ] }
Marc Hadley (Mar 10 2016 at 15:31):
This is quite close to the current representation in that all extensions live in an array and are identified by url. The key difference is that the members of a complex extension (e.g. NCT) are first class children of the extension rather than being nested extensions. You could still add nested extensions as you would now but at least code that understands an extension could path into it directly rather than doing a loop comprehension over the nested extensions.
Josh Mandel (Mar 10 2016 at 15:43):
And you'd say: to identify the properties in a complex extension, look for all properties within an extension other than url
, isModifier
, extension
and modifierExtension
?
Marc Hadley (Mar 10 2016 at 15:47):
You could do that. I was kind of assuming that if you know the extension then you know the properties you are expecting. If you don't know the extension and just want to treat it generically then you can treat all the properties generically.
Josh Mandel (Mar 10 2016 at 15:53):
Agreed, if you "know" the extension you just examine and use the properties you know. That generic treatment is what I was trying to understand/specify.
Marc Hadley (Mar 10 2016 at 15:54):
IOW, if my code knows about the clinical trial extension then it know that there should be an NCT property. Same as if my code knows how to work with Patient resources it knows to expect names and telecoms etc. This is what we meant by treating extensions the same as core elements in our proposed requirements.
Josh Mandel (Mar 10 2016 at 15:54):
i.e. what would the "generic treatment" algorithm look like?
Marc Hadley (Mar 10 2016 at 15:55):
What is your generic treatment algorithm intended to accomplish?
Josh Mandel (Mar 10 2016 at 16:03):
For example, you'd want a generic algorithm that could convert from JSON to XML.
Josh Mandel (Mar 10 2016 at 16:03):
Or one that could display relevant details to a human when you don't know how to compute on an extension.
Marc Hadley (Mar 10 2016 at 16:11):
If we went this route we'd need to figure out the corresponding XML representation. Without giving it too much thought I think we could go with a top level extension element with local name extension and ns URI corresponding to the structure def URL. You'd map properties other than url, isModifier to child elements and map isModifier to an attribute on the extension element.
Josh Mandel (Mar 10 2016 at 16:12):
Yes -- this is the kind of stuff I mean :-)
Marc Hadley (Mar 10 2016 at 16:13):
For human readable display then you can map the JSON to some kind of HTML view of the content, kind of the way Java IDEs display JavaBeans.
Marc Hadley (Mar 10 2016 at 16:14):
Having regular local names rather than URLs would help I think
Josh Mandel (Mar 10 2016 at 16:16):
Quite. I like this, for what it's worth.
Josh Mandel (Mar 10 2016 at 16:17):
How would you distinguish arrays vs. single values?
Josh Mandel (Mar 10 2016 at 16:17):
(In a way that allows round-tripping with XML, "generically").
Marc Hadley (Mar 10 2016 at 16:19):
If the property cardinality is > 1 then always use an array in JSON, use repeating elements in XML.
Marc Hadley (Mar 10 2016 at 16:20):
so if NCT were multivalued then the value would be an array of objects, each with a single valueString property.
Josh Mandel (Mar 10 2016 at 17:09):
If the property cardinality is > 1 then always use an array in JSON, use repeating elements in XML.
The concern with this rule is that you can't tell from the XML how to generate the JSON (you see one element, but maybe it's a repeating list that just happens to have one member in this particular instance).
Marc Hadley (Mar 10 2016 at 20:06):
@Josh Mandel Yes that's an issue. Two alternatives are to always use arrays or to use an array when there is more than one value. The former would be unfortunate if the goal is to make the JSON more natural, the latter adds complexity since code needs to handle both cases whenever a field can have more than one value.
Josh Mandel (Mar 10 2016 at 20:06):
Right. The third option is adding an isArray="true"
attribute to the XML.
Grahame Grieve (Mar 10 2016 at 20:07):
I would never agree to 'use an array when there is more than one value' - in one short step, you destroy the value proposition completely
Grahame Grieve (Mar 10 2016 at 20:07):
When we've discussed this before, we have generally reluctantly come around to adding metadata to xml, but that's going to problematic
Grahame Grieve (Mar 10 2016 at 20:08):
I'm not feeling great about the course of this discussion; it seems to me that we haevn't begun to have the kind of wider discussion that would get this through ballot. Irrespective of the technical merits of any of the proposals.
Marc Hadley (Mar 10 2016 at 20:11):
Any suggestions to get wider input? I'd be happy to write up a new blog post that captures the essence of the discussion so far and shows a couple of examples of the latest proposal.
Grahame Grieve (Mar 10 2016 at 20:13):
well, we're discussing it here - a very few of us. I've had some out of band comments about the discussion but they haven't indicated that people are afraid of the discussion, just the possible outcome. and we've emailed the list, and you've blogged about it. So there's nothing methodological that we haven't done that we usually do. It's just not getting traction with people
Grahame Grieve (Mar 10 2016 at 20:14):
I've done what I can to prod things gently. I could be less gentle, I guess, but I'm not sure it's worth doing that
Marc Hadley (Mar 10 2016 at 20:38):
Looks like there are very few complex extensions currently and for simple extensions I think the current format is OK. It wasn't until we tried to build the first round of CDS extensions with multiple levels of nested extensions that it really occurred to me that a better representation was needed.
Josh Mandel (Mar 10 2016 at 20:39):
+1 I'm with you on this, @Marc Hadley
Grahame Grieve (Mar 10 2016 at 21:10):
yes that's not unreasonable. But CDS extensions on Basic weren't really what we designed extensions for
Grahame Grieve (Mar 10 2016 at 21:11):
ad-hoc extensions to well understood contents is a totally different ball game to taking basic and building a whole set of stuff on it. I looked at that stuff and winced. But not because of syntax, but because other decisions forced us to that point.
Andrew Ross (Mar 10 2016 at 21:13):
Speaking of extensions, I'm working on a CDS app using FHIR that is planning on using extensions to represent relative timings in Order Sets (where there's structure to when actions should be performed, but the start date / patient isn't known). Is there a particular way you all would recommend structuring that, or do you know if there are any modifications to Timing coming down the pipe?
Jason Walonoski (Mar 10 2016 at 21:13):
True, they weren't designed for Basic, but my perception is that there aren't a whole lot of complex extensions out in the wild yet, but I expect that over time there will be. So, fixing complex extensions now to make them easier and nice forever more makes sense.
Grahame Grieve (Mar 10 2016 at 21:16):
There is always proposals to extend the timing data type to make the timing relative to some arbitrary event, but the nature of the event and the linkage vary wildly. So we don't think that putting these details in TIming make sense - we think that this is something that belongs on the context where it is used. At least, that's what I think, and the analysis of reuqirements is certainly wildy variant
Grahame Grieve (Mar 10 2016 at 21:18):
jason - maybe.. but I think they are already easy and nice. Or to be more clear, what we have now is a compromise between 'easy and nice' from various perspectives, and it's not clear that the alternatives we've discussed here represent a more optimal approach overall than the current arrangement
Bryn Rhodes (Mar 10 2016 at 21:20):
@Andrew, we are working on modeling exactly that relationship between elements within the OrderSet resource. Agree with Grahame that the relationships should be stated at the container, rather than on the Timing element directly.
Andrew Ross (Mar 10 2016 at 21:21):
ok, that's good to hear. If you have any examples of what you're thinking so far, or if you have an estimate of the timing (no pun intended) when you think that would be released, it would be great to know
Andrew Ross (Mar 10 2016 at 21:22):
we're hoping that our system will integrate with multiple others, so we can't just make an ad-hoc agreement with one
Bryn Rhodes (Mar 10 2016 at 22:11):
@Andrew Ross I'll get an example over the next few days. Agree about one way to do it, we're putting this in the OrderSet resource itself, it won't be an extension (so it's probably not an appropriate topic for this stream anymore :)).
Andrew Ross (Mar 10 2016 at 22:24):
@Bryn Rhodes awesome :) i appreciate it!
Ewout Kramer (Mar 14 2016 at 17:14):
I personally did not mind the > year old proposal for Json to have the extension url as the object member name, and I think these discussions have converged on that format again. I was at the meeting (it was the connectathon actually) where that extension format was voted down. I also would not mind having "repeat=yes" attribute or whatever in the xml to make interconversion easier.
Pascal Pfiffner (Mar 14 2016 at 18:15):
The main problem I'd have with URLs as object property name is that it "breaks" the JS in JSON, since you can't have property names with /
and .
in JS.
Josh Mandel (Mar 14 2016 at 18:18):
Well, you can't address those properties with the .
operation. You can, of course, with quotes, as in :
var a = { "simple": "as", "can/be": true }; console.log(a.simple, a["can/be"]);
(I know this is already clear to @Pascal Pfiffner. I'm just being explicit/pedantic here.)
Pascal Pfiffner (Mar 14 2016 at 18:20):
Agreed, my argument comes purely from a style perspective.
Grahame Grieve (Mar 14 2016 at 20:11):
@Ewout Kramer - I am not in favour of repeating that just for the sake of it
Last updated: Apr 12 2022 at 19:14 UTC