REST API unkown RM version for non-locatable objects like CONTRIBUTION

CONTRIBUTIONs are not LOCATABLEs so they don’t have a field to specify the rm_version.

When parsing CONTRIBUTION on POST /ehr/$id/contribution, the server doesn’t know which RM version was used to define such payload. Consider this flow:

  1. parse JSON CONTRIBUTION => internal JSON object
  2. validate JSON object with JSON schema => validation errors
  3. if (errors) => return error
  4. else => map JSON object to a list of VERSION and an AUDIT_DETAILS
  5. process versions and audit (validate against OPT, store, etc)

For step 2. the right JSON schema version should be chose to validate the whole CONTRIBUTION, which validates each VERSION and each VERSION.data (COMPOSITION, EHR_STATUS, FOLDER, ROLE, PERSON, …)

If there were small changes between RM versions, and the wrong JSON schema version is used, then some attributes added in newer versions won’t even be validated against the schema.

Then on step 4. the RM version can be retrieved from each VERSION.data.archetype_details.rm_version, for consistency sake, those rm_versions might be the same, and the same as the RM version of the CONTRIBUTION, which we don’t have now.

Then on step 5. when validating against the OPT, the RM version from each VERSION.data is used.

So the issue is for the initial validation against the schema. A workaround would be to get the RM version from VERSION.data, the problem is there are many, so a server that requires those RM versions to be the same, would work this way, but a server that doesn’t required that, might not work. In that case, a sensible option would be to use the minimal RM version found in VERSION.data, it’s not ideal, might leave some attributes without validation for the JSON schema validation, but there is no other way around.

I think it would be useful to have a place to put the rm_version in the JSON/XML object committed by POTS /ehr/$id/contribution, note this is not the RM CONTRIBUTION but the SM CONTRIBUTION class, the one that represents the current HTTP payload from the REST API, which is a relaxed version of the RM CONTRIBUTION, for instance, doesn’t require a CONTRIBUTION.uid to be provided (required by the RM).

I would like to know what others think, thanks!

Also noticed for the CONTRIBUTION to be correctly validated by the JSON Schema, it should have a _type for JSON, and for XML schema, a xsi:type attribute.

I’m not sure this is true - but it is very good that you brought it up. Consider a Problem list, accumulating versions over 20 years in an openEHR EHR. It is very likely that earlier versions of the Compositions are from RM 1.0.4, and later ones from 1.1.0, 1.2.0 etc. If we agree with that (and that’s the reason that we put the attribute rm_version into LOCATABLE.archetype_details), then the JSON schema validation should proceed by looking at the rm_version attribute in each VERSION.data and retrieving the appropriate JSON schema.

The same argument as above holds for any versioned content - it’s just that it is more obvious with managed lists, because of the continuous accumulation of versions over time. But in principle, any Event Composition can be reversioned as well.

@thomas.beale that means for POST /ehr/$id/contribution the HTTP payload, which is a JSON or XML CONTRIBUTION won’t be validated against the schema?

See the request payload here EHR API

I think a better solution is validating the whole payload as a unit, not parts of it, then transform to RM objects to validate against the OPT (only the locatable objects).

Also note I’m not saying we need to change the RM, this SM model openEHR Platform Service Model

Just adding a place for system metadata like the rm_version. Another option would be to change the commit_contribution operation to add a metadata object as parameter here openEHR Platform Service Model

Also note that, even if it’s not in a API request payload, it’s in a response, the EHR resource is neither locatable so we don’t know with which rm_version it complies with, so it’s difficult to automatically know how to process it. For instance in newer RM versions a folders attribute was added, so depending on the RM version a client might want to process that attribute or not. The workaround for a client would be, check if the folders is there and process it if there is, which I know is a trivial answer, but in terms of design and formality, the server already knows that info (rm version) and can help a client by retrieving it. An alternative workaround would be to return the current RM version used by the server via the admin API, but that doesn’t apply to individual EHRs, as you mentioned, there could be EHRs in many different RM versions, as there could be EHR_STATUS, FOLDER, COMPOSITION, PERSON, ROLE, etc.

One thing we need to be sure of is what ‘rm_version’ means. We defined it (AFAIK) to mean the version of the RM component, primarily to capture the version of the content part of the model. There are some parts of the RM - the whole change control (versioning) part for example, that really should be in the BASE component. The notion of RM version doesn’t relate that well to this part of the RM.

If our aim is to treat rm_version as the indicator of the version of the content inside a Version, then we possibly should treat CONTRIBUTION separately and either not worry about RM version for it (or the rest of the Version classes). I’d prefer to move them to the BASE component in fact. You might then argue that we still need to deal with a version indicator, but now it would be ‘base_version’ :wink:

yes we should do something about this, I agree.

Well, if I would speak from my programmer/implementor perspective (in PHP), the back-end “system” uses only one RM (perhaps the latest 1.1.0), which is advertised by the API on “OPTIONS /”, and that is able to coop with previous RM 1.0.2 <-> RM 1.1.0 because they are backwards compatible. That’s why we strive at SEC to not introduce breaking changes, isn’t it?
So in my environment, this (CONTRIBUTION missing RM info) is not an issue at all.
Am I missing something?

Yes, the RM version to which the resource POSTed via HTTP represents.

CONTRIBUTION isn’t content or isn’t it part of the RM?

How I understand it is: CONTRIBUTION is a container for a set of changes to an EHR. If that is mapped to an API resource, which is another model (SM based), and it’s also managed (i.e. versioned and can evolve) then in some place a model version is needed. Call that RM or whatever, but the model version hint in the API is useful.

The problem we have is: the API version management is different from the resource (SM data models) version management. In general what other APIs do is they release an API version (operations) including the resource model, so it’s an atomic set.

We on the other hand define an API and it’s versions independently from the resources used on that API, which now derive from a relaxed RM, which needs to be formalized to the SM as the upstream model than then will be mapped to specific ITS formats for the REST API and any other API technology we might support in the future (already discussed many times, that’s another issue).

If you check the GET operations, for GET contribution it’s the same case: the retrieved resource is not LOCATABLE so the client doesn’t know with which version it complies with without checking the internal versions.data, and as you mentioned, each of those items at versions.data could potentially have a different rm_version value.

Thomas mentioned, in time, your system could have different versions of RM content because the system evolved with the RM releases, I guess what is retrieved in the OPTIONS is the latest supported RM version by the system, but not the RM versions of the content, since as said, those could be in many different versions from years of recording data.

Another question is how the system should behave if it receives a resource that is different than the version advertised in the OPTIONS response?

How do you validate a JSON you get on the POST /ehr/$id/contribution endpoint? I mean the process your system follows. Mine is like what I explained in the first message and at some point I need to choose a JSON schema version according to the RM version, because the system is multi-RM-version.

that is certainly the idea. The only question is what happens when data are shared across openEHR systems and some are on earlier versions of the RM - they will see fields in the data they don’t know about and may not handle them.

I do agree with your general suggestion BTW - that we make appropriate modifications in the SM level models, if we need them for the APIs. That’s exactly the purpose of those models.

That’s certainly an issue, especially when sharing EHRs and CONTRIBUTIONs that don’t have the RM version at the root level.

One quick idea would be to advertise, as @sebastian.iancu mentioned, all the RM versions supported by a system, then when sharing information between systems, some kind of version negotiations might be useful, like saying “System A: I have information in these RM versions, System B: I accept information in these other RM versions”, then some kind of report might be generated to notify about the potential problems to note that some fields might not be processed correctly because of RM version differences.

Though information sharing/integration is a whole different use case, but it’s worth exploring.

Adding to that, if we could in the future release the REST API alongside with the minimal supported SM model and the JSON/XML schemas for the REST resources that represent that SM model, our release set would be more formal and complete, we could even deprecate versions to make future versions of the REST API more maintainable without a lot of legacy.

In that context, I still believe there is value on having the RM version on all the resources that can be pushed to and pulled from the API, unless we explicitly say that the REST API works with just one version of the RM (really one version of the resource schemas representing RM objects), with which I’m OK with, since that would solve the initial issue of not having an RM version specification for non-locatable resources.

1 Like