fhir-fuel / fhir-fuel.github.io

Place to prepare proposal to FHIR about JSON, JSON-Schema, Swagger/OpenAPI, JSON native databases and other JSON-frendly formats (yaml, edn, avro, protobuf etc) and technologies
Other
21 stars 0 forks source link

Primitive extensions #5

Open niquola opened 7 years ago

niquola commented 7 years ago

Problem

In FHIR you could extend primitive types with additional attributes. This encoded in JSON with "_" prefix and has similar to variable type elements problems with collections, schema, databases etc:

{ 
  value: 42'
  _value { extension: [....]}
}

Solution 1

We could apply the json-ld approach and encode primitives with objects:

{ 
  value: {
    @type: "Number",
    number: 42,
    extension: [...]
  }
}

Additionally, we fix weak typed JSON by embedding type labels into object

We pay by deeper paths and some size of Resource (because of additional $type labels):

obj.value vs obj.value.number 

{
  resourceType: "Patient",
  id: "example",
  identifier: [ ... ],
  active: { 
     @type: "boolean"
     boolean: true
  },
  gender: { 
     @type: "code"
     code: "male"
  },
  birthDate: {
    @type: "date",
    date: "1974-12-25",
    extension": [
      {
        "url": "http://hl7.org/fhir/StructureDefinition/patient-birthTime",
        "valueDateTime": "1974-12-25T14:35:45-05:00"
      }
    ]
  }
  deceased: {
    @type: 'boolean',
    boolean: false
  },
  managingOrganization: {
    "reference": "Organization/1"
  }
}

But we simplify typed parsing of JSON because of type information is in the document and does not require lookup in meta-data. We also allow collections of extended primitives.

We could go farther and add $type annotation attribute to other elements (i.e. complex elements or datatypes):

  managingOrganization: {
    "reference": "Organization/1"
  }

  managingOrganization: {
    @type: "Reference",
    "reference": "Organization/1"
  }
niquola commented 6 years ago

Here is new option for primitives:

// in simple case

{"attribute": "primitiveValue"}

// in case with extensions

{"attribute": {"value": ...., "extensions": .....}}
// or
{"attribute": {"<type>": ...., "extensions": .....}}
{"attribute": {"string": ...., "extensions": .....}}
niquola commented 6 years ago

so all of your lookups should be like resource.attr.value OR resource.attr