From 1b2db295c7e9da0e5a2e0614384930f7e83201c4 Mon Sep 17 00:00:00 2001 From: Johannes Marbach Date: Mon, 10 Nov 2025 11:14:23 +0100 Subject: [PATCH] Replace canonical_url and profiles with more specific metadata about the structure definition Signed-off-by: Johannes Marbach --- proposals/4302-fhir-resources.md | 130 +++++++++++++++++++++---------- 1 file changed, 91 insertions(+), 39 deletions(-) diff --git a/proposals/4302-fhir-resources.md b/proposals/4302-fhir-resources.md index d02a421a7..77c22d000 100644 --- a/proposals/4302-fhir-resources.md +++ b/proposals/4302-fhir-resources.md @@ -7,13 +7,44 @@ healthcare-related information. The base building block of FHIR are so-called *r have a type that defines their base schema. This schema can be further customised through one or more *profiles*. -As an example, [`Questionnaire`] is the resource type for medical forms that can be used for various -purposes. This type defines several fields such as an *optional* `title` property containing a human -friendly name for the form. [`ISiKFormularDefinition`], in turn, is a profile on `Questionnaire` -created by Germany's national health agency, gematik, for use within hospitals. It customises the -schema of `Questionnaire` in several ways, such as making `title` required rather than optional. +As an example, [`Questionnaire`] is the resource type for generic medical forms. This type defines +several fields such as an *optional* `title` property containing a human readable name for the form. +[`ISiKFormularDefinition`], in turn, is a profile on `Questionnaire` created by Germany's national +health agency, gematik, for use within hospitals. It customises the schema of `Questionnaire` in +several ways, such as making `title` required rather than optional. -Both resource types and profiles can be uniquely identified by their [canonical URL]. +Profiles can extend either resource types or other profiles, meaning it is possible to build chains +of profiles. Both resource types and profiles are described via [`StructureDefinition`]s which are +uniquely identified by their [canonical URL]. + +``` json5 +{ + // This is the profile ISiKFormularDefinition v5.0.0, created by gematik GmbH + "resourceType": "StructureDefinition", + "id": "ISiKFormularDefinition", + "url": "https://gematik.de/fhir/isik/StructureDefinition/ISiKFormularDefinition", + "version": "5.0.0", + "publisher": "gematik GmbH", + // It extends the base type Questionnaire from FHIR v4.0.1 + "type": "Questionnaire", + "fhirVersion": "4.0.1", + // It is based directly on the base type without intermediary profiles + "baseDefinition": "http://hl7.org/fhir/StructureDefinition/Questionnaire", + // It changes the base type, among others, by making the title field mandatory + "differential": { + "element": [{ + "id": "Questionnaire.title", + "min": 1, + "mustSupport": true, + ... + }, ...]}, + ... +} +``` + +While the above example is trivial, the customisations achievable via profiling can be extensive. As +a result, it is crucial for implementations to understand what profiles are being used when +exchanging data. ## The problems of using FHIR resources in Matrix @@ -27,24 +58,31 @@ render the resource as an interactive form for the user to fill out and send bac Similarly, clients that connect external systems to Matrix may want to automatically process certain resources. For instance, an anamnesis bot may want to export received `QuestionnaireResponse`s into -a surgery's patient management system. Again, the generic MIME type forces such a client to download -the file to determine if it is indeed a `QuestionnaireResponse`. +a hospital's patient management system. Again, the generic MIME type forces such a client to +download the file to determine if it is indeed a `QuestionnaireResponse`. -These problems would be obliterated if FHIR resources were inlined into Matrix events. However, this -isn't always possible due to the [64 KiB event size limit]. Additionally, no suitable event type or -content block exists, as of writing. +These problems would be mitigated to some extent if FHIR resources were inlined into Matrix events. +However, serialized resources contain only limited information about the underlying +`StructureDefinition`. Most importantly the base resource type is missing, making it difficult for +implementations that support a base type but not a specific profile to fall back in a reasonable +way. Furthermore, inlining isn't always possible due to the [64 KiB event size limit] and no +suitable event type or content block exists, as of writing. ## Proposal -To enable the efficient exchange of FHIR resources in either inline or file form, a new event type -`m.fhir.resource` is introduced. This type mandates the following properties in `content`: - -- `canonical_url` (string, required): The resource's [canonical URL], that is the globally unique - identifier defining its base schema. MAY contain a version suffix separated by `|` as per the FHIR - specification. -- `profiles`: (array of strings): The canonical URLs of the profiles the resource conforms to (if - any). The order of elements in the array is arbitrary, similar to FHIR's own [`Meta.profile`] - property. +To enable the compatible and efficient exchange of FHIR resources in either inline or file form, a +new event type `m.fhir` is introduced. This type mandates the following properties in `content`: + +- `m.fhir.structure_definition` (object, required): Information about the resource's + `StructureDefinition`. + - `url` (string, required): The [canonical URL] of the most specific `StructureDefinition` + describing the resource. This is equivalent to [`StructureDefinition.url`]. + - `version` (string, required): The version of the `StructureDefinition`. This is equivalent to + [`StructureDefinition.version`]. + - `type` (string, required): The `StructureDefinition`'s base type. This is equivalent to + [`StructureDefinition.type`]. + - `fhir_version` (string, required): The version of the FHIR specification on which the + `StructureDefinition` is based. This is equivalent to [`StructureDefinition.fhirVersion`]. - `m.fhir.resource` (object, required if `m.file` is missing): The serialised JSON if it fits within the [64 KiB event size limit]. - `m.file` (object, required if `m.fhir.resource` is missing): An [MSC3551] content block describing @@ -52,13 +90,15 @@ To enable the efficient exchange of FHIR resources in either inline or file form ``` json5 { - "type": "m.fhir.resource", + "type": "m.fhir", "content": { // Metadata to help identify the resource - "canonical_url": "http://hl7.org/fhir/StructureDefinition/Questionnaire|4.0.1", - "profiles": [ - "https://gematik.de/fhir/isik/StructureDefinition/ISiKFormularDefinition|5.0.0" - ], + "m.fhir.structure_definition": { + "url": "https://gematik.de/fhir/isik/StructureDefinition/ISiKFormularDefinition", + "version": "5.0.0", + "type": "Questionnaire", + "fhir_version": "4.0.1", + }, // Either: The resource in inline form "m.fhir.resource": { "resourceType": "Questionnaire", @@ -74,36 +114,44 @@ To enable the efficient exchange of FHIR resources in either inline or file form } ``` +The `url` and `version` properties, on the one hand, allow implementations with support for the +particular profile to activate dedicated display or processing logic. The `type` and `fhir_version` +properties, on the other hand, enable implementations *without* support for the specific profile to +offer fallback behaviour if they have generic support for the resource's base type. + ## Potential issues -FHIR includes generic resources such as [`Bundle`] which wrap other resources. The `canonical_url` -will not help clients understand the wrapped content without downloading it in these cases. -Dedicated event types may be introduced in future to cater to these situations. +FHIR includes generic resources such as [`Bundle`] which wrap other resources. The metadata in +`m.fhir.structure_definition` will not help clients understand the wrapped content without +downloading it in these cases. Dedicated event types or further metadata fields may be introduced in +future to cater to these situations. ## Alternatives Dedicated MIME types per resource, version and serialisation format could be introduced. Since FHIR -supports a vast number of resources this doesn't appear practical, however. +supports a vast number of resources and profiles this doesn't appear practical, however. -[RFC 2045] allows MIME types to include modifying parameters. The canonical URL could, therefore, be -included alongside the media type[^1]. +[RFC 2045] allows MIME types to include modifying parameters. The contents of +`m.fhir.structure_definition` could, therefore, be included alongside the media type[^1]. - Content-type: application/fhir+json; canonical_url="http://hl7.org/fhir/patient.html|4.0.1" +``` http +Content-type: application/fhir+json; url="https://gematik.de/fhir/isik/StructureDefinition/ISiKFormularDefinition"; ... +``` -This would allow reusing the `m.file` message type but leaks the resource type to the home server in +This would allow reusing the `m.file` message type but leaks metadata to the home server in [`POST /_matrix/media/v3/upload`]. ## Security considerations Malicious clients could attempt to trick other clients into automatically downloading files by -faking the metadata in `m.fhir.resource` events. As a minimal defense, clients SHOULD sanity-check -the size of the downloaded file by issuing a HEAD request and refuse to download large files without -explicit user consent. +faking the metadata in `m.fhir.structure_definition`. As a minimal defense, clients SHOULD +sanity-check the size of the downloaded file by issuing a HEAD request and refuse to automatically +download large files without explicit user consent. ## Unstable prefix -While this MSC is not considered stable, the event type `m.fhir.resource` should be referred to as -`de.gematik.msc4302.fhir.resource`. +While this MSC is not considered stable, the event type `m.fhir` should be referred to as +`de.gematik.msc4302.fhir`. ## Dependencies @@ -116,11 +164,15 @@ None. [FHIR]: https://hl7.org/fhir/ [`Questionnaire`]: http://hl7.org/fhir/StructureDefinition/Questionnaire [`ISiKFormularDefinition`]: https://gematik.de/fhir/isik/StructureDefinition/ISiKFormularDefinition + [`StructureDefinition`]: https://build.fhir.org/structuredefinition.html [canonical URL]: https://build.fhir.org/references.html#canonical [`m.file`]: https://spec.matrix.org/v1.14/client-server-api/#mfile [`QuestionnaireResponse`]: http://hl7.org/fhir/StructureDefinition/QuestionnaireResponse [64 KiB event size limit]: https://spec.matrix.org/v1.16/client-server-api/#size-limits - [`Meta.profile`]: http://hl7.org/fhir/resource-definitions.html#Meta.profile + [`StructureDefinition.url`]: https://build.fhir.org/structuredefinition-definitions.html#StructureDefinition.url + [`StructureDefinition.version`]: https://build.fhir.org/structuredefinition-definitions.html#StructureDefinition.version + [`StructureDefinition.type`]: https://build.fhir.org/structuredefinition-definitions.html#StructureDefinition.type + [`StructureDefinition.fhirVersion`]: https://build.fhir.org/structuredefinition-definitions.html#StructureDefinition.fhirVersion [MSC3551]: https://github.com/matrix-org/matrix-spec-proposals/pull/3551 [`Bundle`]: http://hl7.org/fhir/StructureDefinition/Bundle [RFC 2045]: https://datatracker.ietf.org/doc/html/rfc2045#section-5