FHIR Chat · Representing Extensions · implementers

Stream: implementers

Topic: Representing Extensions


view this post on Zulip 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.

view this post on Zulip 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.

view this post on Zulip 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

view this post on Zulip Grahame Grieve (Mar 05 2016 at 01:07):

this would also be possible:

view this post on Zulip 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>

view this post on Zulip 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"

view this post on Zulip Grahame Grieve (Mar 05 2016 at 01:10):

is that true about lax? jaxb ignores anything in other namespaces, or it just blows up?

view this post on Zulip Grahame Grieve (Mar 05 2016 at 01:10):

what about other code generators?

view this post on Zulip 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

view this post on Zulip 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?

view this post on Zulip 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?

view this post on Zulip Mark Kramer (Mar 05 2016 at 23:02):

I didn't mean to imply anything, just asking for feedback.

view this post on Zulip 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?

view this post on Zulip 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?

view this post on Zulip 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.

view this post on Zulip 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/

view this post on Zulip 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?

view this post on Zulip 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.

view this post on Zulip 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

view this post on Zulip Grahame Grieve (Mar 07 2016 at 19:05):

note that RDF <> json-ld. We can't use json-ld

view this post on Zulip 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

view this post on Zulip Grahame Grieve (Mar 07 2016 at 19:08):

this question is a very big deal for me in with regard to this proposal

view this post on Zulip Grahame Grieve (Mar 07 2016 at 19:08):

and relates directly to why we can't use json-ld

view this post on Zulip Grahame Grieve (Mar 07 2016 at 19:09):

note that we could also move the type into the manifest too

view this post on Zulip 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)

view this post on Zulip Grahame Grieve (Mar 07 2016 at 21:30):

.. and say.. not .. and way... (don't know why I can't edit that one)

view this post on Zulip 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.

view this post on Zulip Grahame Grieve (Mar 07 2016 at 21:44):

have to repeat the extension definition ad nauseam?

view this post on Zulip 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.

view this post on Zulip 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

view this post on Zulip Marc Hadley (Mar 07 2016 at 21:46):

I feel another example coming on...

view this post on Zulip 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

view this post on Zulip Marc Hadley (Mar 07 2016 at 21:47):

Good point. I think there are pros and cons here.

view this post on Zulip 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.

view this post on Zulip 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

view this post on Zulip Grahame Grieve (Mar 08 2016 at 01:52):

Marc, thinking more about this- I think this has real problems

view this post on Zulip Grahame Grieve (Mar 08 2016 at 01:52):

patient = {...second example above...}
nct = patient["patient-clinicalTrial"].NCT.valueString

view this post on Zulip Grahame Grieve (Mar 08 2016 at 01:53):

only, you can't. you actually have a much worse problem than that the original code

view this post on Zulip 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

view this post on Zulip 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

view this post on Zulip 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

view this post on Zulip Marc Hadley (Mar 08 2016 at 12:57):

I see what you are getting at, but I still think its better. Compare:

view this post on Zulip 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

view this post on Zulip Marc Hadley (Mar 08 2016 at 12:58):

vs

view this post on Zulip 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

view this post on Zulip Grahame Grieve (Mar 08 2016 at 13:00):

so you made complex extensions slightly easier at the price of making simple extensions harder

view this post on Zulip Marc Hadley (Mar 08 2016 at 13:00):

(the second being the proposed, the first being current)

view this post on Zulip 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

view this post on Zulip 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.

view this post on Zulip Grahame Grieve (Mar 08 2016 at 13:02):

here, you have a double loop

view this post on Zulip Grahame Grieve (Mar 08 2016 at 13:02):

to get the name you want.

view this post on Zulip Grahame Grieve (Mar 08 2016 at 13:02):

then use it

view this post on Zulip Grahame Grieve (Mar 08 2016 at 13:02):

as opposed to just looking for the extension you want

view this post on Zulip Marc Hadley (Mar 08 2016 at 13:03):

There's only one loop

view this post on Zulip 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

view this post on Zulip 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

view this post on Zulip 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

view this post on Zulip Grahame Grieve (Mar 08 2016 at 13:05):

it wasn't perfect; we still had to deal with modifier extensions.

view this post on Zulip Grahame Grieve (Mar 08 2016 at 13:05):

so I'm skeptical. I think

view this post on Zulip Marc Hadley (Mar 08 2016 at 13:05):

I included modifiers in my proposal

view this post on Zulip Grahame Grieve (Mar 08 2016 at 13:05):

but lets see other opinions

view this post on Zulip 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"
          }
       }
    }
  }
}

view this post on Zulip 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?

view this post on Zulip Marc Hadley (Mar 08 2016 at 13:08):

localname = patient["@extension"]["@localname"]
nct = patient[localname].NCT.valueString

view this post on Zulip Marc Hadley (Mar 08 2016 at 13:09):

@extension is an object since the keys are unique

view this post on Zulip Grahame Grieve (Mar 08 2016 at 13:10):

so you can only have one extension on an element at once?

view this post on Zulip Marc Hadley (Mar 08 2016 at 13:10):

one @extension with multiple children, one per extension

view this post on Zulip 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?

view this post on Zulip 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
  }
}

view this post on Zulip 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

view this post on Zulip 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

view this post on Zulip Grahame Grieve (Mar 08 2016 at 13:18):

so the code is going to get more complex yet

view this post on Zulip Marc Hadley (Mar 08 2016 at 13:18):

Same goes for the current representation, I didn't put any error handling in that either

view this post on Zulip 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

view this post on Zulip 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

view this post on Zulip 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.

view this post on Zulip 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

view this post on Zulip 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.

view this post on Zulip 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?

view this post on Zulip 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.

view this post on Zulip Grahame Grieve (Mar 08 2016 at 18:59):

HL7 defined extensions - that's a problem, because they're in the same namespace

view this post on Zulip Grahame Grieve (Mar 08 2016 at 18:59):

I missed that

view this post on Zulip 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 ?

view this post on Zulip Grahame Grieve (Mar 08 2016 at 19:12):

no, they're not. scratch that. They are in a differnt namespace (just same root)

view this post on Zulip 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.

view this post on Zulip Marc Hadley (Mar 08 2016 at 20:53):

Easy enough in XPath I guess: /*/*[namespace-uri(.)!="http://hl7.org/fhir"]

view this post on Zulip 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.

view this post on Zulip 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?

view this post on Zulip Lloyd McKenzie (Mar 08 2016 at 21:05):

The use-case is to find extensions for the current node

view this post on Zulip Marc Hadley (Mar 08 2016 at 21:06):

so ./*[namespace-uri(.)!="http://hl7.org/fhir"] in XPath.

view this post on Zulip 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.

view this post on Zulip 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.

view this post on Zulip Marc Hadley (Mar 09 2016 at 16:27):

... or they are out of step with the actual content

view this post on Zulip Lloyd McKenzie (Mar 09 2016 at 16:33):

Yeah, that can be a challenge too.

view this post on Zulip 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.

view this post on Zulip 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.

view this post on Zulip 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"
          }
       }
    }
  }
}

view this post on Zulip 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).

view this post on Zulip 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?

view this post on Zulip 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.

view this post on Zulip Lloyd McKenzie (Mar 09 2016 at 18:51):

It seems weird to have two globally unique names

view this post on Zulip Marc Hadley (Mar 09 2016 at 18:51):

OIDs are globally unique without being URIs...

view this post on Zulip Lloyd McKenzie (Mar 09 2016 at 18:51):

Right. But we don't use OIDs

view this post on Zulip Marc Hadley (Mar 09 2016 at 18:51):

I think you mentioned earlier that developers didn't like using URIs as keys

view this post on Zulip Lloyd McKenzie (Mar 09 2016 at 18:52):

Right. They didn't like long strings as keys.

view this post on Zulip Rick Geimer (Mar 09 2016 at 18:52):

OIDs can be URIs. urn:oid:OID-HERE

view this post on Zulip 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.

view this post on Zulip 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.

view this post on Zulip 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)

view this post on Zulip Rick Geimer (Mar 09 2016 at 18:53):

But in general I find my developers like the URIs with somewhat meaningful names.

view this post on Zulip 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.

view this post on Zulip 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 . . .

view this post on Zulip 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

view this post on Zulip Rick Geimer (Mar 09 2016 at 18:56):

Exactly Lloyd.

view this post on Zulip 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.

view this post on Zulip Grahame Grieve (Mar 09 2016 at 20:39):

Marc - indeed that was already rejected, and I think it's better than your proposal.

view this post on Zulip Grahame Grieve (Mar 09 2016 at 20:39):

which suggests to me that all this discussion is actually moot. :-(

view this post on Zulip 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.

view this post on Zulip 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?

view this post on Zulip 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"
            }
         }
      }
    }
  ]
}

view this post on Zulip 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.

view this post on Zulip 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?

view this post on Zulip 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.

view this post on Zulip 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.

view this post on Zulip 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.

view this post on Zulip Josh Mandel (Mar 10 2016 at 15:54):

i.e. what would the "generic treatment" algorithm look like?

view this post on Zulip Marc Hadley (Mar 10 2016 at 15:55):

What is your generic treatment algorithm intended to accomplish?

view this post on Zulip Josh Mandel (Mar 10 2016 at 16:03):

For example, you'd want a generic algorithm that could convert from JSON to XML.

view this post on Zulip 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.

view this post on Zulip 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.

view this post on Zulip Josh Mandel (Mar 10 2016 at 16:12):

Yes -- this is the kind of stuff I mean :-)

view this post on Zulip 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.

view this post on Zulip Marc Hadley (Mar 10 2016 at 16:14):

Having regular local names rather than URLs would help I think

view this post on Zulip Josh Mandel (Mar 10 2016 at 16:16):

Quite. I like this, for what it's worth.

view this post on Zulip Josh Mandel (Mar 10 2016 at 16:17):

How would you distinguish arrays vs. single values?

view this post on Zulip Josh Mandel (Mar 10 2016 at 16:17):

(In a way that allows round-tripping with XML, "generically").

view this post on Zulip 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.

view this post on Zulip 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.

view this post on Zulip 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).

view this post on Zulip 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.

view this post on Zulip Josh Mandel (Mar 10 2016 at 20:06):

Right. The third option is adding an isArray="true" attribute to the XML.

view this post on Zulip 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

view this post on Zulip 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

view this post on Zulip 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.

view this post on Zulip 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.

view this post on Zulip 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

view this post on Zulip 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

view this post on Zulip 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.

view this post on Zulip Josh Mandel (Mar 10 2016 at 20:39):

+1 I'm with you on this, @Marc Hadley

view this post on Zulip 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

view this post on Zulip 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.

view this post on Zulip 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?

view this post on Zulip 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.

view this post on Zulip 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

view this post on Zulip 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

view this post on Zulip 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.

view this post on Zulip 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

view this post on Zulip 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

view this post on Zulip 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 :)).

view this post on Zulip Andrew Ross (Mar 10 2016 at 22:24):

@Bryn Rhodes awesome :) i appreciate it!

view this post on Zulip 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.

view this post on Zulip 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.

view this post on Zulip 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.)

view this post on Zulip Pascal Pfiffner (Mar 14 2016 at 18:20):

Agreed, my argument comes purely from a style perspective.

view this post on Zulip 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