Very interesting @borut.jures ! I am no GraphQL expert, but have asked experienced colleagues to have a closer look.
I wonder about some initial things:
- The intended/possible context of GraphQL query/mutation execution etc. A single field or subtreee of a versioned openEHR COMPOSITION is not modifiable without making and commiting a new version of the entire COMPOSITION (logically via a CONTRIBUTION). Are you considering using this in a “contribution builder” of some kind e.g. as described in: CONTRIBUTION builder supporting collaborative (multi user, multi device) editing? GraphQL? Operational Transformation? ? (If so, we could load an existing version of a COMPOSITION (or several different compositions etc) into the builder, query and manipulate it (them) and then when we feel finished tell the builder to committ the changed objects via a new CONTRIBUTION.
- The leaf data types, like different instances of DV_QUANTITY at different paths in listing 1 below seem to repeat the basic structure of DV_QUANTITY under new names
BloodPressureDataHistoryEventAnyEventDataBloodPressureItemDiastolicValueDvQuantity
has the same content as the correspondingBloodPressureDataHistoryEventAnyEventDataBloodPressureItemDiastolicValueDvQuantity
This touches a bit upon what @Seref wrote about repeated data types in self contained worlds in
Separating Models from Implementation - #79 by Seref- If the model/subtree is an unconstrained type (like DV_QUANTITY) I’d guess having and repeating a generic corresponding structure would be more readable
- If the model/subtree is a constrained type like the systolic and diastolic subtrees actually are in the archetype (constrained min/max values, chosen units, different terminology bindings etc) then specially named repetitions would be understandable. But maybe that is something you aim for later?
Since I am a GraphQL noob I don’t know if the graphql-constraints-spec is used in tools etc or if it is currently just a seemingly useful suggestion. Or maybe constraints are ususally taken care of by object definitions in client implementations (e.g. constraints built in to a generated TypeScript class for BloodPressure)? - The openEHR backend (CDR) will enfoce constraint checks later anyway…
The structure in Listing 2 below is very readable by the way.
Listing 1 - graphql\schema.graphql
type BloodPressureDataHistoryEventAnyEventDataBloodPressureItem {
# Peak systemic arterial blood pressure - measured in systolic or contraction phase of the heart cycle.
systolic: BloodPressureDataHistoryEventAnyEventDataBloodPressureItemSystolic
# Minimum systemic arterial blood pressure - measured in the diastolic or relaxation phase of the heart cycle.
diastolic: BloodPressureDataHistoryEventAnyEventDataBloodPressureItemDiastolic
# ...example snippet abbreviated here...
}
# The leaf variant of `ITEM`, to which a `DATA_VALUE` instance is attached.
# RM type: ELEMENT
type BloodPressureDataHistoryEventAnyEventDataBloodPressureItemSystolic {
value: BloodPressureDataHistoryEventAnyEventDataBloodPressureItemSystolicValue
}
type BloodPressureDataHistoryEventAnyEventDataBloodPressureItemSystolicValue {
dvQuantity: BloodPressureDataHistoryEventAnyEventDataBloodPressureItemSystolicValueDvQuantity
}
# ...example snippet abbreviated here...
# RM type: DV_QUANTITY
type BloodPressureDataHistoryEventAnyEventDataBloodPressureItemDiastolicValueDvQuantity {
property: TerminologyCode
magnitude: Float
units: String
precision: Int
}
# ...example snippet abbreviated here...
# RM type: DV_QUANTITY
type BloodPressureDataHistoryEventAnyEventDataBloodPressureItemSystolicValueDvQuantity {
property: TerminologyCode
magnitude: Float
units: String
precision: Int
}
Listing 2 - structure from generated\typescript-apollo-angular.ts and many of the other example files
bloodPressure {
data {
history {
events {
a24HourAverage {
data {
itemTree {
items {
systolic {
value {
dvQuantity {
property {
terminologyId
codeString
terminologyVersion
}
magnitude
units
precision
}
}
# ...example snippet abbreviated here...