Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Variable type (union, polymorphic) elements #2

Open
niquola opened this issue Jun 16, 2017 · 4 comments
Open

Variable type (union, polymorphic) elements #2

niquola opened this issue Jun 16, 2017 · 4 comments

Comments

@niquola
Copy link
Member

niquola commented Jun 16, 2017

Vision

Some resource’s elements could have variable type, in specification such
elements have [x] postfix (for example Observation.value[x]). In JSON
representation such elements encoded by substitution of postfix with specific
title-cased type name:

{ resourceType: "Observation", valueString: "....", ...}
{ resourceType: "Observation", valueNumber: 42, .... }

Issue Statement

a) This approach to representation force innecessary constraint: Elements that
have a choice of data type cannot repeat. I.e. They must have a maximum
cardinality of 1. There is no absolute reason to force this besides format
representation.

b) On the other side, most of Object Oriented implementations of FHIR usually
provide convenient accessors to “polymorphic elements” like
observation.getValue(), but when you work with data, without any object wrapper,
you have to manually handle this. For example, check which specific
Observation.value your are dealing with by iterating through the object.

c) JSON schema is a very popular way to specify the shape of JSON objects. But it’s
features is not enough to describe, that only one of postifexed keys are allowed
in the object (i.e. valueString or valueQuantity) or if the element is required say at
least one of the keys should be present.

d) Implementation of FHIR search for missing elements, like
Observation?value:missing=true, in databases
native support of JSON is tricky with this representation.

These problems probably is consequence of contradiction, which was put into
representation — we represent one entity (variable type attribute) with multiple
entities (postfixed keys).

Solution 1

Here is variant of encoding, which solves listed concerns:

{ someProp: { @type: "string", string: "..."}}
{ someProp: { @type: "Quantity", Quantity: {....}}}

Variable type attribute could be encoded with object with meta attribute, for example, @type
(or any other meta name) and value with a key named after type.
So fix inconsistency with keys and explicitly embed
type information into representation. We, also, relax arity one constraint and could have collections of variable type elements.

a. collections of [x]

{ someProp: [{type: "String", string: "..."}, {type: "Number", number: 42}], ...}

b. logical access to the element

object.someProp.string

c. JSON schema required and mutial exclusion

{ 
  properties: { 
    someProp: { 
       properties: {
          @type: {enum: ["string", "Number"]}, // we could use $data to bind type with type key
          string: ....
          number: ....
        },
        minProperties: 2, // require at least one type key
        maxProperties: 2, // at most one key
        required: ["type"]
    }
  },
  required: [someProp] // require polymorphic element

}

d. In databases we could access for search or indexes

SELECT * FROM resource WHERE json_path(res, 'someProp') is NULL;
SELECT * FROM resource WHERE json_path(res, 'someProp.string') ilike '%something%';

Solution 2

When the first solution uses key named after type (i.e. someProp.string), another approach have
a fixed key:

{ someProp: { @type: "string", value: "..."}}
{ someProp: { @type: "Quantity", value: {...}}}

CONS

Having different types under the same path create problems for schemata,
for example, when you index json in elastic-search, you have to provide mappings to
identify element types (see https://www.elastic.co/guide/en/elasticsearch/reference/current/mapping.html) and you could
not have different types for the same path.

Also, this is error-prone in javascript applications - most of the times someProp.value will work
until incompatible with code variant will arrive :(

@niquola
Copy link
Member Author

niquola commented Jun 8, 2018

Argument for types as keys - we can easy implement fhirpath expressions like res.attr.as(Quantity) by just translating it into res.attr.Quantity expression, which is supported by most off json databases.

@grahamegrieve
Copy link

mystifying how this is meaningfully better than just translating into res.attrQuantity instead of res.attr.Quantity... you'll have to find better justifications than that

@niquola
Copy link
Member Author

niquola commented Jun 9, 2018

attrQuantity does not allow collections - which means it’s logicaly wrong. Also this is very difficult to express require in json schema and :missing search. Potentially users can put two elements attrType1 and attrType2 on the same resource and this format does not prevent such mistakes, as well it’s not obvious how to constraint it with json schema. It’s indistinguishable from just attributes postfixed with type, like birthDate. When working with this representation we need string operations on keys - that’s bad sign too. Too many signs ;) So semantically this is one element, but represented by different attributes.

@grahamegrieve
Copy link

that's a better argument...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants