Generating GraphQL from OPTs

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:

  1. 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.
  2. 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 corresponding BloodPressureDataHistoryEventAnyEventDataBloodPressureItemDiastolicValueDvQuantity
    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?
      image 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...
1 Like