Suggestion for extensibility in JSON

I just got started working on the search part of my FHIR server - supports only json -.
Took a look at the documentation for searching here (http://hl7.org/implement/standards/fhir//search.html) then realized all search parameters are domain resources that have to saved and added to the conformance statement.
I told myself lets see how would one search parameter look like, So I’ve taken a look at this one here (http://hl7.org/implement/standards/fhir//searchparameter-example-extension.json.html)
this one is using an extension as search parameter, and I couldn’t help ask

  • on the first level:

  • Why FHIR is using properties that applies only to xml like xpath, xpathUsage for a specification that is supposed to work for both xml and json.

  • I thought you could use dot separated path string like in structure definition then I’ve found out that is not applicable here - extension is used as a search parameter - and the problem is with how extensibility works and how it’s defined and that lead to the second level.

  • on the second level

  • I’ve found out that the way extensibility works as defined here (http://hl7.org/implement/standards/fhir//extensibility.html) for JSON is not good.
    The way it works now that it has it’s json looking like this :-

var patient = {
  "name" : {
  "extension" : [{
    "url" : "http://hl7.org/fhir/StructureDefinition/iso-21090-name-use",
    "valueCode" : "I"
  }],
  "text" : "Chief Red Cloud"
}

At first sight it may look ok to select an extension for this name element in Javascript for example :-
patient.name.extension[0].valueCode

but if we use the second exmple on the page where the patient has multiple extensions

{
  "resourceType" : "Patient",
  "extension" : [{
    "url" : "http://hl7.org/fhir/StructureDefinition/patient-clinicalTrial",
    "extension" : [{
      "url" : "NCT",
      "valueString" : "123456789"
    }, {
      "url" : "period",
      "valuePeriod" : {
         "start" : "2009-03-14"
      }   
    },  {
      "url" : "reason",
      "valueCodeableConcept" : {
          "coding" : {
             "system" : "http://acme.org/codes/general",
             "code" : "tt14j",
          }
       }
    }]
  }]
  ... other data for patient ...
}

to assign each of these extensions to a variable we will have to go throught a nasty process of looping in this array and add couple of conditional statements to get extension’s variable(name)\value pair (plus the original problem of the search parameter resource having xml specific properties).

the code may look like something like this - though there are prettier ways to do this - :-

let NCT, period, reason;
patient.extension.map((k,v) => {
  if(v.url === 'NCT') {
    NCT = v;
  } else if (v.url === 'period') {
    period = v;
  } else if (v.url === 'reason') {
    reason = v;
  }
})

or may we will to resort to an external library to handle this - there is one called defiant.js that can use xpath against JSON.

On the other hand, on xml you can simply use the one and only attribute selector like it’s no bodies business :D.

  • I don’t remember the syntax, I’ve exactly left xml/xpath a couple of years ago
<xsl:match select="patient">
<xsl:value-of select="extension/extension[@url='NCT']/*@value" />
<xsl:value-of select="extension/extension[@url='period']/@value" />
<xsl:value-of select="extension/extension[@url='reason']/@value" />
</xsl:match>

See, piece of cake.

Solution for JSON

We all know that JSON is object based and follows the notion of the key/value pair for defining data structure.

So instead of having the extension as an ** array of objects **

"extension" : [{
    "url" : "http://hl7.org/fhir/StructureDefinition/patient-clinicalTrial",
    "extension" : [{
      "url" : "NCT",
      "valueString" : "123456789"
    }, {
      "url" : "period",
      "valuePeriod" : {
         "start" : "2009-03-14"
      }   
    },  {
      "url" : "reason",
      "valueCodeableConcept" : {
          "coding" : {
             "system" : "http://acme.org/codes/general",
             "code" : "tt14j",
          }
       }
    }]
  }]

It should be simply a plain object with many keys representing each extension.

"extension" : {
  "clinicalTrial": {
    "url" : "http://hl7.org/fhir/StructureDefinition/patient-clinicalTrial",
    "extension" : {
      "NCT": {
      "url" : "NCT",
      "valueString" : "123456789"
      },
      "period": {
        "url" : "period",
        "valuePeriod" : {
           "start" : "2009-03-14"
        }   
      },  
      "reason": {
        "url" : "reason",
        "valueCodeableConcept" : {
            "coding" : {
               "system" : "http://acme.org/codes/general",
               "code" : "tt14j",
            }
         }
      }
    }
  }
}

Then we can simply do something like this

extension.clinicalTrial.extension.NCT

It will be easy to figure out if it’s an extension because in most of the cases an extension will have a parent that is either an extension, a modifier extension or _fieldname if it’s an extension for a field with primitive datatype.

I know I am not fully aware of all the aspects of the issue, So I am really looking forward to knowing your thoughts and feedback.

in your example, where does the name ‘clinicalTrial’ come from? It looks like it’s something new to standardise to me .And it looks like you’d have to magically ‘know’ that extension… you couldn’t just read it as ‘any extension’

We actually tried simply using the extension URL as the key, and it was roundly defeated at ballot. That wasn’t to everyone’s liking, and the question of a better way to represent extensions in JSON still bubbles away. I don’t think we’ve considered this particular variant though?

I am just using an example from FHIR documentation extensibility page.
I don’t know much about any clinicalTrial use case myself.

I think URL and Key should be different things, In JSON syntax there is nothing against using a URL string as the Key. But it will be troubling to type in a long url over and over inside the code - still better than the way it is right now -.

It will still have the url field inside it to recognize the extension.

There is further discussion about this here: https://chat.fhir.org/#narrow/stream/implementers/subject/JSON.20Extensions

1 Like

I’ve taken a look at the chat their, looks like there are people who have thought this through and there are a lots of solutions that can be implemented