OpenAPI schemas generated from BMM files

The thing is that RM/AM is useful for already openEHR-savvy people creating openEHR tools and CDRs. Those that do that likely already have some kind of solution (e.g. hand coded), thus no rush and less activity seen. What is missing is modern version of the TDO/TDS/TDD approach as discussed in the thread Separating Models from Implementation - #75 by erik.sundvall.

(Of course some of the generated general RM class descriptions are usable also as e.g. data type descriptions to be included in the template specific “streamlined/flattened” approach)

1 Like

Yes that is certainly true for some use cases. I am not sure what you are suggesting, but if it is to use paths in a way similar to what is described on a wikipage from 2012 by @thomas.beale https://openehr.atlassian.net/wiki/spaces/spec/pages/4915205/Ocean+EhrGate+-+Composition+Builder+programming+example, then note @heath.frankel’s comment at the bottom of that page regarding what developers not familiar with openEHR thought:

1 Like

I agree with @heath.frankel’s comment. Many attempts were made to “simplify” OPTs and “protect” developers from learning openEHR AM/RM. None made them happy.

My opinion is that if developers don’t want to familiarise themselves with the openEHR approach to data modeling, they shouldn’t keep asking the community for yet another “simplification” that would enable them to work with openEHR. Just count the number of different simplifications that are useful to their authors but are still not appealing to developers who demand such simplifications. Everything is too complicated for them. I’m afraid that any solution will be too complicated with that way of thinking.

I hope there will always be developers that are willing to spend some time learning before they start building openEHR solutions.

I attempt to skip all the intermediary XML/JSON/paths… and work directly with the model. The prerequisite to this approach is to have the AM/RM available in the frontend app. Then you can write code like:

ehrGate.CreateComposition("Lipids")

…and it will use the models built on the base of OPT to serialize the data for the COMPOSITION that can be sent to the CDR.

Here is an example toJson() method for COMPOSITION that calls toJson() for its attributes (which do the same for their attributes,… turtles all the way down):

1 Like

I don’t want to be disrespectful to anybody but I believe there is a minimum effort required before starting to build software. I wasn’t afraid of flying until:

“The Max has been grounded since March 2019, after some badly written software caused two crashes that killed 346 people. And while Boeing has received plenty of scrutiny for its bad code.”

Boeing 737 Software Issue

3 Likes

There really is. People want the power of modern aircraft, mobile telephony, AI radiology assessments and video-conferencing, while also claiming that ‘every kid should program’ and ‘anyone can build software’. Sorry, but it’s not the same software.

NB: I am talking about back-end systems here. Low-code development is something else - high-level tooling for domain and UX experts to build quality applications. THis also can’t be done by just anyone because it requires some knowledge of cognitive psychology, usability and many other things. There’s really no escape anywhere for actually learning properly what needs to be learned before trying to build things. And the learning has to start with understanding the problem space.

The reason most software fails.

Awesome work BTW @NeoEHR - again!

3 Likes

I now tried to explain my concerns a bit more in post 77 of Separating Models from Implementation - #77 by erik.sundvall

1 Like

I’m guessing the minimum effort required comment was meant for me.

I was developing software that was sold to hospitals around the world nearly twenty years ago.

But I do Domain driven design, as do many others. Including Martin Fowler and Eric Evans.
https://martinfowler.com/tags/domain%20driven%20design.html

Fairly sure they, and me have spent enough time in software to decide that we think this is the best approach.

The comment wasn’t meant for you.
It was part of the discussion with @erik.sundvall and @joostholslag . I hope they didn’t take it personally :flushed:

I appreciate the discussion you brought to openEHR and acknowledge your experience :peace_symbol:

I have thought deeply about your recommendations and even generated requested OpenAPI schemas to help you and others that would like to use them.

3 Likes

What fits DDD much better is to have a single level model.

This is a crude attempt using some JSON (it’s an instance rather than definition, and not pulled through all the RM attributes, but hopefully self explanatory)
AdverseReactions.json (1.0 KB)

Coded Entry is a reusable type I introduced…

1 Like

Also had a look at the EHR Toolkit provided by @pablo. This is template JSON export to EHRServer, which is getting closer but still refers to RM types that I as a consumer don’t know anything about.

I could however probably write a parser for this, without having to use archie or get into ADL.

JSON EHR Server format.json (123.9 KB)

1 Like

That looks very verbose if you are looking for streamlined formats and a single level model. I’d guess most developers would consider the e.g. structSDT format described in Simplified Data Template (SDT) simpler to work with, see example below. It is autogenerated from templates and has sensible defaults for many use cases.

{
    "ctx": {
      "language": "en",
      "territory": "SI",
      "composer_name": "matijak_test"
    },
    "vitals": {
      "vitals": [
        {
          "body_temperature": [
            {
              "any_event": [
                {
                  "description_of_thermal_stress": [
                    "Test description of symptoms"
                  ],
                  "temperature": [
                    {
                      "|magnitude": 37.2,
                      "|unit": "°C"
                    }
                  ],
                  "symptoms": [
                    {
                      "|code": "at0.64",
                      "|value": "Chills / rigor / shivering",
                      "|terminology": "local"
                    }
                  ],
                  "time": [
                    "2014-01-22T15:18:07.339+01:00"
                  ]
                }
              ]
            }
          ]
        }
      ],
      "context": [
        {
          "setting": [
            {
              "|code": "238",
              "|value": "other care",
              "|terminology": "openehr"
            }
          ],
          "start_time": [
            "2014-01-22T15:18:07.339+01:00"
          ]
        }
      ]
    }
  }

You can play with it in e.g. https://www.ehrscape.com/api-explorer.html as shown in post 61 in Separating Models from Implementation - #61 by erik.sundvall

Also see post #12 in Separating Models from Implementation - #12 by erik.sundvall

1 Like

There are useful ideas in this book (which I have had for years) but they apply to reference model development, and indeed I have used some.

Trying to use this approach for a really large volatile domain doesn’t work. It can work for a constrained domain though. You might envisage treating each application, or each clinical subdomain as its own thing, and doing DDD to solve it. THe problem is that there are literally thousands of clinical data points/groups common across all those domains (vital signs, common labs, for a start), so you quickly have to get into mapping data from each separate app with its own model to a common model. How will that be represented? As 5,000 Java classes? And the data set definitions are changing all the time, so it’s a giant moving target.

Martin Fowler almost figured out the correct answer in Analysis Patterns - have a look at the diagrams with the dotted lines, to distinguish between classes representing things, and classes representing kinds of things. All he had to do was to go one step further and get out of the class model for the second category.

2 Likes

So, this is part of the point. We think the future is going to see EPR’s broken up into several specialised app’s working across fairly fixed domains. An app for dementia, and app for joint replacements. Ecosystem is the buzz word they usually use.

OpenEHR could provide the clinical models these apps are built on…

1 Like

I’ll just go out on a limb and say there are no fixed domains :wink: I’ve never even seen a fixed single app data set. Everything changes, all the time…

1 Like

A post was merged into an existing topic: Separating Models from Implementation

I’d like to disagree a bit here. I think FLAT and STRUCTURED formats + TDS + our own TDOs are covering different needs.

For example, within HiGHmed, we use TDS/TDD for data integration with Intersystems Ensemble and Mapforce

FLAT FORMAT has become quite handy for some app development and is used in multiple low-code tools like the ones provided by Better and Solid Clouds

We were able to build a full AQL query editor using our DTO model (+ AQL parser) and some more applications which require some stronger focus on backend processing.

Long story short: I don’t think there can be one single perfect format that will make everybody happy to develop software. Having the openEHR RM and Templates allows to make flexible transformations and tweaks to serve different needs.

Surely the openAPI approach would complement this by enabling some convenient support in multiple language. Hence, I think the situation has drastically improved since 2013 and an average developer is able to have their first “hello world” app up and running within 1-2 days. Not saying we cannot further improve but this is more about open educational resources and not the available tooling.

1 Like

You reaffirm my point - those that invested their time in learning the openEHR data model and architecture, have no problem using these simplified data formats. The formats are useful.

Those that want to skip the learning part are usually not satisfied with any simplified data format. Even when the same format was successfully used by the developers from the first paragraph.

1 Like

Summary: TDS/TDD is B2B-oriented; flat formats (and TDOs by the way) are C2B-oriented.

I think this diagram from a few years a go is still not a bad way to think about the various kinds of mappings needed to get from canonical-based formats to OPT-specific messages (TDD-type things) and micro-APIs (TDOs).

Indeed.

Well I think we need a bit more tool chain in existence first, but that’s the idea for sure.

Yep. But they may not want to skip the learning; perhaps their employer never gives them time or space to go and get training on new methods. That is what is needed, as per my other post.

The big advantage with FHIR is that people are experiencing success very early. Once you bought into it (because it is deceptively easy), you are going down the rabbit hole. There is just no simple solution for health IT, this is more about perception and psychology.

5 Likes

@ToStupidForOpenEHR that is the canonical openEHR XML format for a COMPOSITION inside the VERSION object (a wrapper which adds versioning info to the clinical document), with a canonical JSON transformation applied (which is supported by the EHRServer to commit data, but is not a canonical JSON). That is why you see those @ attributes there, those are XML attributes in JSON notation.

If you check the new openEHR Toolkit , it provides a tool to generate canonical JSON, which is the same data but slightly different, and openEHR valid, JSON format.